Auto merge of #131792 - matthiaskrgr:rollup-480nwg4, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #130822 (Add `from_ref` and `from_mut` constructors to `core::ptr::NonNull`.) - #131381 (Implement edition 2024 match ergonomics restrictions) - #131594 (rustdoc: Rename "object safe" to "dyn compatible") - #131686 (Add fast-path when computing the default visibility) - #131699 (Try to improve error messages involving aliases in the solver) - #131757 (Ignore lint-non-snake-case-crate#proc_macro_ on targets without unwind) - #131783 (Fix explicit_iter_loop in rustc_serialize) - #131788 (Fix mismatched quotation mark) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
7342830c05
@ -690,16 +690,29 @@ fn check_pat_ident(
|
||||
|
||||
BindingMode(def_br, Mutability::Mut)
|
||||
} else {
|
||||
// `mut` resets binding mode on edition <= 2021
|
||||
self.typeck_results
|
||||
// `mut` resets the binding mode on edition <= 2021
|
||||
*self
|
||||
.typeck_results
|
||||
.borrow_mut()
|
||||
.rust_2024_migration_desugared_pats_mut()
|
||||
.insert(pat_info.top_info.hir_id);
|
||||
.entry(pat_info.top_info.hir_id)
|
||||
.or_default() |= pat.span.at_least_rust_2024();
|
||||
BindingMode(ByRef::No, Mutability::Mut)
|
||||
}
|
||||
}
|
||||
BindingMode(ByRef::No, mutbl) => BindingMode(def_br, mutbl),
|
||||
BindingMode(ByRef::Yes(_), _) => user_bind_annot,
|
||||
BindingMode(ByRef::Yes(_), _) => {
|
||||
if matches!(def_br, ByRef::Yes(_)) {
|
||||
// `ref`/`ref mut` overrides the binding mode on edition <= 2021
|
||||
*self
|
||||
.typeck_results
|
||||
.borrow_mut()
|
||||
.rust_2024_migration_desugared_pats_mut()
|
||||
.entry(pat_info.top_info.hir_id)
|
||||
.or_default() |= pat.span.at_least_rust_2024();
|
||||
}
|
||||
user_bind_annot
|
||||
}
|
||||
};
|
||||
|
||||
if bm.0 == ByRef::Yes(Mutability::Mut)
|
||||
@ -2204,14 +2217,14 @@ fn check_pat_ref(
|
||||
}
|
||||
} else {
|
||||
// Reset binding mode on old editions
|
||||
|
||||
if pat_info.binding_mode != ByRef::No {
|
||||
pat_info.binding_mode = ByRef::No;
|
||||
|
||||
self.typeck_results
|
||||
*self
|
||||
.typeck_results
|
||||
.borrow_mut()
|
||||
.rust_2024_migration_desugared_pats_mut()
|
||||
.insert(pat_info.top_info.hir_id);
|
||||
.entry(pat_info.top_info.hir_id)
|
||||
.or_default() |= pat.span.at_least_rust_2024();
|
||||
}
|
||||
}
|
||||
|
||||
@ -2262,6 +2275,7 @@ fn check_pat_ref(
|
||||
(err, err)
|
||||
}
|
||||
};
|
||||
|
||||
self.check_pat(inner, inner_ty, pat_info);
|
||||
ref_ty
|
||||
}
|
||||
|
@ -635,7 +635,7 @@ fn visit_adjustments(&mut self, span: Span, hir_id: HirId) {
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
fn visit_rust_2024_migration_desugared_pats(&mut self, hir_id: hir::HirId) {
|
||||
if self
|
||||
if let Some(is_hard_error) = self
|
||||
.fcx
|
||||
.typeck_results
|
||||
.borrow_mut()
|
||||
@ -645,7 +645,9 @@ fn visit_rust_2024_migration_desugared_pats(&mut self, hir_id: hir::HirId) {
|
||||
debug!(
|
||||
"node is a pat whose match ergonomics are desugared by the Rust 2024 migration lint"
|
||||
);
|
||||
self.typeck_results.rust_2024_migration_desugared_pats_mut().insert(hir_id);
|
||||
self.typeck_results
|
||||
.rust_2024_migration_desugared_pats_mut()
|
||||
.insert(hir_id, is_hard_error);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1651,7 +1651,6 @@
|
||||
/// ### Example
|
||||
///
|
||||
/// ```rust,edition2021
|
||||
/// #![feature(ref_pat_eat_one_layer_2024)]
|
||||
/// #![warn(rust_2024_incompatible_pat)]
|
||||
///
|
||||
/// if let Some(&a) = &Some(&0u8) {
|
||||
@ -1672,12 +1671,10 @@
|
||||
pub RUST_2024_INCOMPATIBLE_PAT,
|
||||
Allow,
|
||||
"detects patterns whose meaning will change in Rust 2024",
|
||||
@feature_gate = ref_pat_eat_one_layer_2024;
|
||||
// FIXME uncomment below upon stabilization
|
||||
/*@future_incompatible = FutureIncompatibleInfo {
|
||||
@future_incompatible = FutureIncompatibleInfo {
|
||||
reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024),
|
||||
reference: "123076",
|
||||
};*/
|
||||
};
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
|
@ -73,9 +73,10 @@ pub struct TypeckResults<'tcx> {
|
||||
/// Stores the actual binding mode for all instances of [`BindingMode`].
|
||||
pat_binding_modes: ItemLocalMap<BindingMode>,
|
||||
|
||||
/// Top-level patterns whose match ergonomics need to be desugared
|
||||
/// by the Rust 2021 -> 2024 migration lint.
|
||||
rust_2024_migration_desugared_pats: ItemLocalSet,
|
||||
/// Top-level patterns whose match ergonomics need to be desugared by the Rust 2021 -> 2024
|
||||
/// migration lint. The boolean indicates whether the emitted diagnostic should be a hard error
|
||||
/// (if any of the incompatible pattern elements are in edition 2024).
|
||||
rust_2024_migration_desugared_pats: ItemLocalMap<bool>,
|
||||
|
||||
/// Stores the types which were implicitly dereferenced in pattern binding modes
|
||||
/// for later usage in THIR lowering. For example,
|
||||
@ -418,15 +419,15 @@ pub fn pat_adjustments_mut(&mut self) -> LocalTableInContextMut<'_, Vec<Ty<'tcx>
|
||||
LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.pat_adjustments }
|
||||
}
|
||||
|
||||
pub fn rust_2024_migration_desugared_pats(&self) -> LocalSetInContext<'_> {
|
||||
LocalSetInContext {
|
||||
pub fn rust_2024_migration_desugared_pats(&self) -> LocalTableInContext<'_, bool> {
|
||||
LocalTableInContext {
|
||||
hir_owner: self.hir_owner,
|
||||
data: &self.rust_2024_migration_desugared_pats,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn rust_2024_migration_desugared_pats_mut(&mut self) -> LocalSetInContextMut<'_> {
|
||||
LocalSetInContextMut {
|
||||
pub fn rust_2024_migration_desugared_pats_mut(&mut self) -> LocalTableInContextMut<'_, bool> {
|
||||
LocalTableInContextMut {
|
||||
hir_owner: self.hir_owner,
|
||||
data: &mut self.rust_2024_migration_desugared_pats,
|
||||
}
|
||||
|
@ -265,7 +265,7 @@ mir_build_pointer_pattern = function pointers and raw pointers not derived from
|
||||
|
||||
mir_build_privately_uninhabited = pattern `{$witness_1}` is currently uninhabited, but this variant contains private fields which may become inhabited in the future
|
||||
|
||||
mir_build_rust_2024_incompatible_pat = the semantics of this pattern will change in edition 2024
|
||||
mir_build_rust_2024_incompatible_pat = patterns are not allowed to reset the default binding mode in edition 2024
|
||||
|
||||
mir_build_rustc_box_attribute_error = `#[rustc_box]` attribute used incorrectly
|
||||
.attributes = no other attributes may be applied
|
||||
|
@ -983,6 +983,8 @@ pub(crate) struct Rust2024IncompatiblePat {
|
||||
|
||||
pub(crate) struct Rust2024IncompatiblePatSugg {
|
||||
pub(crate) suggestion: Vec<(Span, String)>,
|
||||
/// Whether the incompatibility is a hard error because a relevant span is in edition 2024.
|
||||
pub(crate) is_hard_error: bool,
|
||||
}
|
||||
|
||||
impl Subdiagnostic for Rust2024IncompatiblePatSugg {
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
pub(crate) use self::check_match::check_match;
|
||||
use crate::errors::*;
|
||||
use crate::fluent_generated as fluent;
|
||||
use crate::thir::util::UserAnnotatedTyHelpers;
|
||||
|
||||
struct PatCtxt<'a, 'tcx> {
|
||||
@ -48,18 +49,28 @@ pub(super) fn pat_from_hir<'a, 'tcx>(
|
||||
typeck_results,
|
||||
rust_2024_migration_suggestion: typeck_results
|
||||
.rust_2024_migration_desugared_pats()
|
||||
.contains(pat.hir_id)
|
||||
.then_some(Rust2024IncompatiblePatSugg { suggestion: Vec::new() }),
|
||||
.get(pat.hir_id)
|
||||
.map(|&is_hard_error| Rust2024IncompatiblePatSugg {
|
||||
suggestion: Vec::new(),
|
||||
is_hard_error,
|
||||
}),
|
||||
};
|
||||
let result = pcx.lower_pattern(pat);
|
||||
debug!("pat_from_hir({:?}) = {:?}", pat, result);
|
||||
if let Some(sugg) = pcx.rust_2024_migration_suggestion {
|
||||
tcx.emit_node_span_lint(
|
||||
lint::builtin::RUST_2024_INCOMPATIBLE_PAT,
|
||||
pat.hir_id,
|
||||
pat.span,
|
||||
Rust2024IncompatiblePat { sugg },
|
||||
);
|
||||
if sugg.is_hard_error {
|
||||
let mut err =
|
||||
tcx.dcx().struct_span_err(pat.span, fluent::mir_build_rust_2024_incompatible_pat);
|
||||
err.subdiagnostic(sugg);
|
||||
err.emit();
|
||||
} else {
|
||||
tcx.emit_node_span_lint(
|
||||
lint::builtin::RUST_2024_INCOMPATIBLE_PAT,
|
||||
pat.hir_id,
|
||||
pat.span,
|
||||
Rust2024IncompatiblePat { sugg },
|
||||
);
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
|
@ -119,6 +119,7 @@
|
||||
use rustc_session::CodegenUnits;
|
||||
use rustc_session::config::{DumpMonoStatsFormat, SwitchWithOptPath};
|
||||
use rustc_span::symbol::Symbol;
|
||||
use rustc_target::spec::SymbolVisibility;
|
||||
use tracing::debug;
|
||||
|
||||
use crate::collector::{self, MonoItemCollectionStrategy, UsageMap};
|
||||
@ -904,6 +905,11 @@ fn mono_item_visibility<'tcx>(
|
||||
}
|
||||
|
||||
fn default_visibility(tcx: TyCtxt<'_>, id: DefId, is_generic: bool) -> Visibility {
|
||||
// Fast-path to avoid expensive query call below
|
||||
if tcx.sess.default_visibility() == SymbolVisibility::Interposable {
|
||||
return Visibility::Default;
|
||||
}
|
||||
|
||||
let export_level = if is_generic {
|
||||
// Generic functions never have export-level C.
|
||||
SymbolExportLevel::Rust
|
||||
@ -913,6 +919,7 @@ fn default_visibility(tcx: TyCtxt<'_>, id: DefId, is_generic: bool) -> Visibilit
|
||||
_ => SymbolExportLevel::Rust,
|
||||
}
|
||||
};
|
||||
|
||||
match export_level {
|
||||
// C-export level items remain at `Default` to allow C code to
|
||||
// access and interpose them.
|
||||
|
@ -6,6 +6,7 @@
|
||||
use rustc_type_ir::fold::TypeFoldable;
|
||||
use rustc_type_ir::inherent::*;
|
||||
use rustc_type_ir::lang_items::TraitSolverLangItem;
|
||||
use rustc_type_ir::solve::inspect;
|
||||
use rustc_type_ir::visit::TypeVisitableExt as _;
|
||||
use rustc_type_ir::{self as ty, Interner, Upcast as _, elaborate};
|
||||
use tracing::{debug, instrument};
|
||||
@ -288,6 +289,25 @@ pub(super) fn assemble_and_evaluate_candidates<G: GoalKind<D>>(
|
||||
let Ok(normalized_self_ty) =
|
||||
self.structurally_normalize_ty(goal.param_env, goal.predicate.self_ty())
|
||||
else {
|
||||
// FIXME: We register a fake candidate when normalization fails so that
|
||||
// we can point at the reason for *why*. I'm tempted to say that this
|
||||
// is the wrong way to do this, though.
|
||||
let result =
|
||||
self.probe(|&result| inspect::ProbeKind::RigidAlias { result }).enter(|this| {
|
||||
let normalized_ty = this.next_ty_infer();
|
||||
let alias_relate_goal = Goal::new(
|
||||
this.cx(),
|
||||
goal.param_env,
|
||||
ty::PredicateKind::AliasRelate(
|
||||
goal.predicate.self_ty().into(),
|
||||
normalized_ty.into(),
|
||||
ty::AliasRelationDirection::Equate,
|
||||
),
|
||||
);
|
||||
this.add_goal(GoalSource::AliasWellFormed, alias_relate_goal);
|
||||
this.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
|
||||
});
|
||||
assert_eq!(result, Err(NoSolution));
|
||||
return vec![];
|
||||
};
|
||||
|
||||
|
@ -983,7 +983,7 @@ pub(super) fn add_item_bounds_for_hidden_type(
|
||||
hidden_ty,
|
||||
&mut goals,
|
||||
);
|
||||
self.add_goals(GoalSource::Misc, goals);
|
||||
self.add_goals(GoalSource::AliasWellFormed, goals);
|
||||
}
|
||||
|
||||
// Do something for each opaque/hidden pair defined with `def_id` in the
|
||||
|
@ -15,7 +15,7 @@
|
||||
use crate::solve::inspect::ProbeKind;
|
||||
use crate::solve::{
|
||||
BuiltinImplSource, CandidateSource, Certainty, EvalCtxt, Goal, GoalSource, MaybeCause,
|
||||
NoSolution, QueryResult,
|
||||
NoSolution, QueryResult, Reveal,
|
||||
};
|
||||
|
||||
impl<D, I> EvalCtxt<'_, D>
|
||||
@ -37,13 +37,64 @@ pub(super) fn compute_normalizes_to_goal(
|
||||
match normalize_result {
|
||||
Ok(res) => Ok(res),
|
||||
Err(NoSolution) => {
|
||||
let Goal { param_env, predicate: NormalizesTo { alias, term } } = goal;
|
||||
self.relate_rigid_alias_non_alias(param_env, alias, ty::Invariant, term)?;
|
||||
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||
self.probe(|&result| ProbeKind::RigidAlias { result }).enter(|this| {
|
||||
let Goal { param_env, predicate: NormalizesTo { alias, term } } = goal;
|
||||
this.add_rigid_constraints(param_env, alias)?;
|
||||
this.relate_rigid_alias_non_alias(param_env, alias, ty::Invariant, term)?;
|
||||
this.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Register any obligations that are used to validate that an alias should be
|
||||
/// treated as rigid.
|
||||
///
|
||||
/// An alias may be considered rigid if it fails normalization, but we also don't
|
||||
/// want to consider aliases that are not well-formed to be rigid simply because
|
||||
/// they fail normalization.
|
||||
///
|
||||
/// For example, some `<T as Trait>::Assoc` where `T: Trait` does not hold, or an
|
||||
/// opaque type whose hidden type doesn't actually satisfy the opaque item bounds.
|
||||
fn add_rigid_constraints(
|
||||
&mut self,
|
||||
param_env: I::ParamEnv,
|
||||
rigid_alias: ty::AliasTerm<I>,
|
||||
) -> Result<(), NoSolution> {
|
||||
let cx = self.cx();
|
||||
match rigid_alias.kind(cx) {
|
||||
// Projections are rigid only if their trait ref holds,
|
||||
// and the GAT where-clauses hold.
|
||||
ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst => {
|
||||
let trait_ref = rigid_alias.trait_ref(cx);
|
||||
self.add_goal(GoalSource::AliasWellFormed, Goal::new(cx, param_env, trait_ref));
|
||||
Ok(())
|
||||
}
|
||||
ty::AliasTermKind::OpaqueTy => {
|
||||
match param_env.reveal() {
|
||||
// In user-facing mode, paques are only rigid if we may not define it.
|
||||
Reveal::UserFacing => {
|
||||
if rigid_alias
|
||||
.def_id
|
||||
.as_local()
|
||||
.is_some_and(|def_id| self.can_define_opaque_ty(def_id))
|
||||
{
|
||||
Err(NoSolution)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
// Opaques are never rigid in reveal-all mode.
|
||||
Reveal::All => Err(NoSolution),
|
||||
}
|
||||
}
|
||||
// FIXME(generic_const_exprs): we would need to support generic consts here
|
||||
ty::AliasTermKind::UnevaluatedConst => Err(NoSolution),
|
||||
// Inherent and weak types are never rigid. This type must not be well-formed.
|
||||
ty::AliasTermKind::WeakTy | ty::AliasTermKind::InherentTy => Err(NoSolution),
|
||||
}
|
||||
}
|
||||
|
||||
/// Normalize the given alias by at least one step. If the alias is rigid, this
|
||||
/// returns `NoSolution`.
|
||||
#[instrument(level = "trace", skip(self), ret)]
|
||||
@ -124,6 +175,7 @@ fn probe_and_match_goal_against_assumption(
|
||||
ecx.instantiate_normalizes_to_term(goal, assumption_projection_pred.term);
|
||||
|
||||
// Add GAT where clauses from the trait's definition
|
||||
// FIXME: We don't need these, since these are the type's own WF obligations.
|
||||
ecx.add_goals(
|
||||
GoalSource::Misc,
|
||||
cx.own_predicates_of(goal.predicate.def_id())
|
||||
@ -179,7 +231,8 @@ fn consider_impl_candidate(
|
||||
.map(|pred| goal.with(cx, pred));
|
||||
ecx.add_goals(GoalSource::ImplWhereBound, where_clause_bounds);
|
||||
|
||||
// Add GAT where clauses from the trait's definition
|
||||
// Add GAT where clauses from the trait's definition.
|
||||
// FIXME: We don't need these, since these are the type's own WF obligations.
|
||||
ecx.add_goals(
|
||||
GoalSource::Misc,
|
||||
cx.own_predicates_of(goal.predicate.def_id())
|
||||
|
@ -288,7 +288,7 @@ fn decode(d: &mut D) -> Rc<T> {
|
||||
impl<S: Encoder, T: Encodable<S>> Encodable<S> for [T] {
|
||||
default fn encode(&self, s: &mut S) {
|
||||
s.emit_usize(self.len());
|
||||
for e in self.iter() {
|
||||
for e in self {
|
||||
e.encode(s);
|
||||
}
|
||||
}
|
||||
@ -527,7 +527,7 @@ fn decode(d: &mut D) -> ThinVec<T> {
|
||||
impl<S: Encoder, T: Encodable<S>> Encodable<S> for VecDeque<T> {
|
||||
fn encode(&self, s: &mut S) {
|
||||
s.emit_usize(self.len());
|
||||
for e in self.iter() {
|
||||
for e in self {
|
||||
e.encode(s);
|
||||
}
|
||||
}
|
||||
@ -547,7 +547,7 @@ impl<S: Encoder, K, V> Encodable<S> for BTreeMap<K, V>
|
||||
{
|
||||
fn encode(&self, e: &mut S) {
|
||||
e.emit_usize(self.len());
|
||||
for (key, val) in self.iter() {
|
||||
for (key, val) in self {
|
||||
key.encode(e);
|
||||
val.encode(e);
|
||||
}
|
||||
@ -571,7 +571,7 @@ impl<S: Encoder, T> Encodable<S> for BTreeSet<T>
|
||||
{
|
||||
fn encode(&self, s: &mut S) {
|
||||
s.emit_usize(self.len());
|
||||
for e in self.iter() {
|
||||
for e in self {
|
||||
e.encode(s);
|
||||
}
|
||||
}
|
||||
@ -595,7 +595,7 @@ impl<E: Encoder, K, V, S> Encodable<E> for HashMap<K, V, S>
|
||||
{
|
||||
fn encode(&self, e: &mut E) {
|
||||
e.emit_usize(self.len());
|
||||
for (key, val) in self.iter() {
|
||||
for (key, val) in self {
|
||||
key.encode(e);
|
||||
val.encode(e);
|
||||
}
|
||||
@ -621,7 +621,7 @@ impl<E: Encoder, T, S> Encodable<E> for HashSet<T, S>
|
||||
{
|
||||
fn encode(&self, s: &mut E) {
|
||||
s.emit_usize(self.len());
|
||||
for e in self.iter() {
|
||||
for e in self {
|
||||
e.encode(s);
|
||||
}
|
||||
}
|
||||
@ -646,7 +646,7 @@ impl<E: Encoder, K, V, S> Encodable<E> for indexmap::IndexMap<K, V, S>
|
||||
{
|
||||
fn encode(&self, e: &mut E) {
|
||||
e.emit_usize(self.len());
|
||||
for (key, val) in self.iter() {
|
||||
for (key, val) in self {
|
||||
key.encode(e);
|
||||
val.encode(e);
|
||||
}
|
||||
@ -672,7 +672,7 @@ impl<E: Encoder, T, S> Encodable<E> for indexmap::IndexSet<T, S>
|
||||
{
|
||||
fn encode(&self, s: &mut E) {
|
||||
s.emit_usize(self.len());
|
||||
for e in self.iter() {
|
||||
for e in self {
|
||||
e.encode(s);
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_next_trait_solver::solve::{GenerateProofTree, HasChanged, SolverDelegateEvalExt as _};
|
||||
use tracing::instrument;
|
||||
use tracing::{instrument, trace};
|
||||
|
||||
use super::Certainty;
|
||||
use super::delegate::SolverDelegate;
|
||||
@ -401,6 +401,7 @@ fn non_trivial_candidates<'a>(
|
||||
nested_goal.source(),
|
||||
GoalSource::ImplWhereBound
|
||||
| GoalSource::InstantiateHigherRanked
|
||||
| GoalSource::AliasWellFormed
|
||||
) && match self.consider_ambiguities {
|
||||
true => {
|
||||
matches!(
|
||||
@ -415,6 +416,13 @@ fn non_trivial_candidates<'a>(
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// Prefer a non-rigid candidate if there is one.
|
||||
if candidates.len() > 1 {
|
||||
candidates.retain(|candidate| {
|
||||
!matches!(candidate.kind(), inspect::ProbeKind::RigidAlias { .. })
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -429,8 +437,11 @@ fn span(&self) -> rustc_span::Span {
|
||||
self.obligation.cause.span
|
||||
}
|
||||
|
||||
#[instrument(level = "trace", skip(self, goal), fields(goal = ?goal.goal()))]
|
||||
fn visit_goal(&mut self, goal: &inspect::InspectGoal<'_, 'tcx>) -> Self::Result {
|
||||
let candidates = self.non_trivial_candidates(goal);
|
||||
trace!(candidates = ?candidates.iter().map(|c| c.kind()).collect::<Vec<_>>());
|
||||
|
||||
let [candidate] = candidates.as_slice() else {
|
||||
return ControlFlow::Break(self.obligation.clone());
|
||||
};
|
||||
@ -464,17 +475,13 @@ fn visit_goal(&mut self, goal: &inspect::InspectGoal<'_, 'tcx>) -> Self::Result
|
||||
polarity: ty::PredicatePolarity::Positive,
|
||||
}))
|
||||
}
|
||||
ty::PredicateKind::Clause(
|
||||
ty::ClauseKind::WellFormed(_) | ty::ClauseKind::Projection(..),
|
||||
)
|
||||
| ty::PredicateKind::AliasRelate(..) => ChildMode::PassThrough,
|
||||
_ => {
|
||||
return ControlFlow::Break(self.obligation.clone());
|
||||
}
|
||||
_ => ChildMode::PassThrough,
|
||||
};
|
||||
|
||||
let mut impl_where_bound_count = 0;
|
||||
for nested_goal in candidate.instantiate_nested_goals(self.span()) {
|
||||
trace!(nested_goal = ?(nested_goal.goal(), nested_goal.source(), nested_goal.result()));
|
||||
|
||||
let make_obligation = |cause| Obligation {
|
||||
cause,
|
||||
param_env: nested_goal.goal().param_env,
|
||||
@ -501,7 +508,7 @@ fn visit_goal(&mut self, goal: &inspect::InspectGoal<'_, 'tcx>) -> Self::Result
|
||||
(_, GoalSource::InstantiateHigherRanked) => {
|
||||
obligation = self.obligation.clone();
|
||||
}
|
||||
(ChildMode::PassThrough, _) => {
|
||||
(ChildMode::PassThrough, _) | (_, GoalSource::AliasWellFormed) => {
|
||||
obligation = make_obligation(self.obligation.cause.clone());
|
||||
}
|
||||
}
|
||||
|
@ -292,7 +292,8 @@ fn candidates_recur(
|
||||
| inspect::ProbeKind::Root { .. }
|
||||
| inspect::ProbeKind::TryNormalizeNonRigid { .. }
|
||||
| inspect::ProbeKind::TraitCandidate { .. }
|
||||
| inspect::ProbeKind::OpaqueTypeStorageLookup { .. } => {
|
||||
| inspect::ProbeKind::OpaqueTypeStorageLookup { .. }
|
||||
| inspect::ProbeKind::RigidAlias { .. } => {
|
||||
// Nested probes have to prove goals added in their parent
|
||||
// but do not leak them, so we truncate the added goals
|
||||
// afterwards.
|
||||
@ -316,7 +317,8 @@ fn candidates_recur(
|
||||
inspect::ProbeKind::Root { result }
|
||||
| inspect::ProbeKind::TryNormalizeNonRigid { result }
|
||||
| inspect::ProbeKind::TraitCandidate { source: _, result }
|
||||
| inspect::ProbeKind::OpaqueTypeStorageLookup { result } => {
|
||||
| inspect::ProbeKind::OpaqueTypeStorageLookup { result }
|
||||
| inspect::ProbeKind::RigidAlias { result } => {
|
||||
// We only add a candidate if `shallow_certainty` was set, which means
|
||||
// that we ended up calling `evaluate_added_goals_and_make_canonical_response`.
|
||||
if let Some(shallow_certainty) = shallow_certainty {
|
||||
|
@ -177,7 +177,8 @@ fn to_selection<'tcx>(
|
||||
| ProbeKind::UpcastProjectionCompatibility
|
||||
| ProbeKind::OpaqueTypeStorageLookup { result: _ }
|
||||
| ProbeKind::Root { result: _ }
|
||||
| ProbeKind::ShadowedEnvProbing => {
|
||||
| ProbeKind::ShadowedEnvProbing
|
||||
| ProbeKind::RigidAlias { result: _ } => {
|
||||
span_bug!(span, "didn't expect to assemble trait candidate from {:#?}", cand.kind())
|
||||
}
|
||||
})
|
||||
|
@ -135,4 +135,6 @@ pub enum ProbeKind<I: Interner> {
|
||||
ShadowedEnvProbing,
|
||||
/// Try to unify an opaque type with an existing key in the storage.
|
||||
OpaqueTypeStorageLookup { result: QueryResult<I> },
|
||||
/// Checking that a rigid alias is well-formed.
|
||||
RigidAlias { result: QueryResult<I> },
|
||||
}
|
||||
|
@ -130,6 +130,10 @@ pub enum GoalSource {
|
||||
ImplWhereBound,
|
||||
/// Instantiating a higher-ranked goal and re-proving it.
|
||||
InstantiateHigherRanked,
|
||||
/// Predicate required for an alias projection to be well-formed.
|
||||
/// This is used in two places: projecting to an opaque whose hidden type
|
||||
/// is already registered in the opaque type storage, and for rigid projections.
|
||||
AliasWellFormed,
|
||||
}
|
||||
|
||||
#[derive_where(Clone; I: Interner, Goal<I, P>: Clone)]
|
||||
|
@ -153,6 +153,7 @@
|
||||
#![feature(isqrt)]
|
||||
#![feature(lazy_get)]
|
||||
#![feature(link_cfg)]
|
||||
#![feature(non_null_from_ref)]
|
||||
#![feature(offset_of_enum)]
|
||||
#![feature(panic_internals)]
|
||||
#![feature(ptr_alignment_type)]
|
||||
|
@ -230,6 +230,24 @@ pub const fn new(ptr: *mut T) -> Option<Self> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts a reference to a `NonNull` pointer.
|
||||
#[unstable(feature = "non_null_from_ref", issue = "130823")]
|
||||
#[rustc_const_unstable(feature = "non_null_from_ref", issue = "130823")]
|
||||
#[inline]
|
||||
pub const fn from_ref(r: &T) -> Self {
|
||||
// SAFETY: A reference cannot be null.
|
||||
unsafe { NonNull { pointer: r as *const T } }
|
||||
}
|
||||
|
||||
/// Converts a mutable reference to a `NonNull` pointer.
|
||||
#[unstable(feature = "non_null_from_ref", issue = "130823")]
|
||||
#[rustc_const_unstable(feature = "non_null_from_ref", issue = "130823")]
|
||||
#[inline]
|
||||
pub const fn from_mut(r: &mut T) -> Self {
|
||||
// SAFETY: A mutable reference cannot be null.
|
||||
unsafe { NonNull { pointer: r as *mut T } }
|
||||
}
|
||||
|
||||
/// Performs the same functionality as [`std::ptr::from_raw_parts`], except that a
|
||||
/// `NonNull` pointer is returned, as opposed to a raw `*const` pointer.
|
||||
///
|
||||
@ -1749,9 +1767,8 @@ impl<T: ?Sized> From<&mut T> for NonNull<T> {
|
||||
///
|
||||
/// This conversion is safe and infallible since references cannot be null.
|
||||
#[inline]
|
||||
fn from(reference: &mut T) -> Self {
|
||||
// SAFETY: A mutable reference cannot be null.
|
||||
unsafe { NonNull { pointer: reference as *mut T } }
|
||||
fn from(r: &mut T) -> Self {
|
||||
NonNull::from_mut(r)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1761,8 +1778,7 @@ impl<T: ?Sized> From<&T> for NonNull<T> {
|
||||
///
|
||||
/// This conversion is safe and infallible since references cannot be null.
|
||||
#[inline]
|
||||
fn from(reference: &T) -> Self {
|
||||
// SAFETY: A reference cannot be null.
|
||||
unsafe { NonNull { pointer: reference as *const T } }
|
||||
fn from(r: &T) -> Self {
|
||||
NonNull::from_ref(r)
|
||||
}
|
||||
}
|
||||
|
@ -1450,7 +1450,7 @@ pub(crate) fn is_notable_trait(&self, tcx: TyCtxt<'_>) -> bool {
|
||||
pub(crate) fn safety(&self, tcx: TyCtxt<'_>) -> hir::Safety {
|
||||
tcx.trait_def(self.def_id).safety
|
||||
}
|
||||
pub(crate) fn is_object_safe(&self, tcx: TyCtxt<'_>) -> bool {
|
||||
pub(crate) fn is_dyn_compatible(&self, tcx: TyCtxt<'_>) -> bool {
|
||||
tcx.is_dyn_compatible(self.def_id)
|
||||
}
|
||||
}
|
||||
|
@ -2002,7 +2002,7 @@ fn init_id_map() -> FxHashMap<Cow<'static, str>, usize> {
|
||||
map.insert("required-associated-consts".into(), 1);
|
||||
map.insert("required-methods".into(), 1);
|
||||
map.insert("provided-methods".into(), 1);
|
||||
map.insert("object-safety".into(), 1);
|
||||
map.insert("dyn-compatibility".into(), 1);
|
||||
map.insert("implementors".into(), 1);
|
||||
map.insert("synthetic-implementors".into(), 1);
|
||||
map.insert("implementations-list".into(), 1);
|
||||
|
@ -934,16 +934,18 @@ fn trait_item(w: &mut Buffer, cx: &mut Context<'_>, m: &clean::Item, t: &clean::
|
||||
let cache = &cloned_shared.cache;
|
||||
let mut extern_crates = FxIndexSet::default();
|
||||
|
||||
if !t.is_object_safe(cx.tcx()) {
|
||||
if !t.is_dyn_compatible(cx.tcx()) {
|
||||
// FIXME(dyn_compat_renaming): Update the URL once the Reference is updated.
|
||||
write_section_heading(
|
||||
w,
|
||||
"Object Safety",
|
||||
"object-safety",
|
||||
"Dyn Compatibility",
|
||||
"dyn-compatibility",
|
||||
None,
|
||||
&format!(
|
||||
"<div class=\"object-safety-info\">This trait is <b>not</b> \
|
||||
<a href=\"{base}/reference/items/traits.html#object-safety\">\
|
||||
object safe</a>.</div>",
|
||||
"<div class=\"dyn-compatibility-info\"><p>This trait is <b>not</b> \
|
||||
<a href=\"{base}/reference/items/traits.html#object-safety\">dyn compatible</a>.</p>\
|
||||
<p><i>In older versions of Rust, dyn compatibility was called \"object safety\", \
|
||||
so this trait is not object safe.</i></p></div>",
|
||||
base = crate::clean::utils::DOC_RUST_LANG_ORG_CHANNEL
|
||||
),
|
||||
);
|
||||
|
@ -315,10 +315,10 @@ fn filter_items<'a>(
|
||||
);
|
||||
sidebar_assoc_items(cx, it, blocks);
|
||||
|
||||
if !t.is_object_safe(cx.tcx()) {
|
||||
if !t.is_dyn_compatible(cx.tcx()) {
|
||||
blocks.push(LinkBlock::forced(
|
||||
Link::new("object-safety", "Object Safety"),
|
||||
"object-safety-note",
|
||||
Link::new("dyn-compatibility", "Dyn Compatibility"),
|
||||
"dyn-compatibility-note",
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -672,7 +672,7 @@ fn from_clean(trait_: clean::Trait, renderer: &JsonRenderer<'_>) -> Self {
|
||||
let tcx = renderer.tcx;
|
||||
let is_auto = trait_.is_auto(tcx);
|
||||
let is_unsafe = trait_.safety(tcx) == rustc_hir::Safety::Unsafe;
|
||||
let is_object_safe = trait_.is_object_safe(tcx);
|
||||
let is_object_safe = trait_.is_dyn_compatible(tcx);
|
||||
let clean::Trait { items, generics, bounds, .. } = trait_;
|
||||
Trait {
|
||||
is_auto,
|
||||
|
@ -19,30 +19,30 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
|
||||
debug i => _22;
|
||||
debug x => _23;
|
||||
}
|
||||
scope 17 (inlined <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next) {
|
||||
scope 18 (inlined <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next) {
|
||||
let mut _14: &mut std::slice::Iter<'_, T>;
|
||||
let mut _15: std::option::Option<&T>;
|
||||
let mut _19: (usize, bool);
|
||||
let mut _20: (usize, &T);
|
||||
scope 18 {
|
||||
scope 19 {
|
||||
let _18: usize;
|
||||
scope 23 {
|
||||
scope 24 {
|
||||
}
|
||||
}
|
||||
scope 19 {
|
||||
scope 20 {
|
||||
scope 26 (inlined <Option<(usize, &T)> as FromResidual<Option<Infallible>>>::from_residual) {
|
||||
scope 20 {
|
||||
scope 21 {
|
||||
scope 27 (inlined <Option<(usize, &T)> as FromResidual<Option<Infallible>>>::from_residual) {
|
||||
}
|
||||
}
|
||||
}
|
||||
scope 21 {
|
||||
scope 22 {
|
||||
scope 22 {
|
||||
scope 23 {
|
||||
}
|
||||
}
|
||||
scope 24 (inlined <Option<&T> as Try>::branch) {
|
||||
scope 25 (inlined <Option<&T> as Try>::branch) {
|
||||
let mut _16: isize;
|
||||
let _17: &T;
|
||||
scope 25 {
|
||||
scope 26 {
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -59,29 +59,31 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
|
||||
let _9: *const T;
|
||||
scope 7 {
|
||||
}
|
||||
scope 11 (inlined without_provenance::<T>) {
|
||||
scope 12 (inlined without_provenance::<T>) {
|
||||
}
|
||||
scope 12 (inlined NonNull::<T>::as_ptr) {
|
||||
scope 13 (inlined NonNull::<T>::as_ptr) {
|
||||
}
|
||||
scope 13 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
|
||||
scope 14 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
|
||||
}
|
||||
}
|
||||
scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) {
|
||||
let mut _4: *const [T];
|
||||
scope 9 (inlined NonNull::<[T]>::from_ref) {
|
||||
let mut _4: *const [T];
|
||||
}
|
||||
}
|
||||
scope 9 (inlined NonNull::<[T]>::cast::<T>) {
|
||||
scope 10 (inlined NonNull::<[T]>::cast::<T>) {
|
||||
let mut _5: *const T;
|
||||
scope 10 (inlined NonNull::<[T]>::as_ptr) {
|
||||
scope 11 (inlined NonNull::<[T]>::as_ptr) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
scope 14 (inlined <std::slice::Iter<'_, T> as Iterator>::enumerate) {
|
||||
scope 15 (inlined Enumerate::<std::slice::Iter<'_, T>>::new) {
|
||||
scope 15 (inlined <std::slice::Iter<'_, T> as Iterator>::enumerate) {
|
||||
scope 16 (inlined Enumerate::<std::slice::Iter<'_, T>>::new) {
|
||||
}
|
||||
}
|
||||
scope 16 (inlined <Enumerate<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
|
||||
scope 17 (inlined <Enumerate<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
|
||||
}
|
||||
|
||||
bb0: {
|
||||
|
@ -34,29 +34,31 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
|
||||
let _9: *const T;
|
||||
scope 7 {
|
||||
}
|
||||
scope 11 (inlined without_provenance::<T>) {
|
||||
scope 12 (inlined without_provenance::<T>) {
|
||||
}
|
||||
scope 12 (inlined NonNull::<T>::as_ptr) {
|
||||
scope 13 (inlined NonNull::<T>::as_ptr) {
|
||||
}
|
||||
scope 13 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
|
||||
scope 14 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
|
||||
}
|
||||
}
|
||||
scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) {
|
||||
let mut _4: *const [T];
|
||||
scope 9 (inlined NonNull::<[T]>::from_ref) {
|
||||
let mut _4: *const [T];
|
||||
}
|
||||
}
|
||||
scope 9 (inlined NonNull::<[T]>::cast::<T>) {
|
||||
scope 10 (inlined NonNull::<[T]>::cast::<T>) {
|
||||
let mut _5: *const T;
|
||||
scope 10 (inlined NonNull::<[T]>::as_ptr) {
|
||||
scope 11 (inlined NonNull::<[T]>::as_ptr) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
scope 14 (inlined <std::slice::Iter<'_, T> as Iterator>::enumerate) {
|
||||
scope 15 (inlined Enumerate::<std::slice::Iter<'_, T>>::new) {
|
||||
scope 15 (inlined <std::slice::Iter<'_, T> as Iterator>::enumerate) {
|
||||
scope 16 (inlined Enumerate::<std::slice::Iter<'_, T>>::new) {
|
||||
}
|
||||
}
|
||||
scope 16 (inlined <Enumerate<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
|
||||
scope 17 (inlined <Enumerate<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
|
||||
}
|
||||
|
||||
bb0: {
|
||||
|
@ -31,25 +31,27 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
|
||||
let _9: *const T;
|
||||
scope 7 {
|
||||
}
|
||||
scope 11 (inlined without_provenance::<T>) {
|
||||
scope 12 (inlined without_provenance::<T>) {
|
||||
}
|
||||
scope 12 (inlined NonNull::<T>::as_ptr) {
|
||||
scope 13 (inlined NonNull::<T>::as_ptr) {
|
||||
}
|
||||
scope 13 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
|
||||
scope 14 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
|
||||
}
|
||||
}
|
||||
scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) {
|
||||
let mut _4: *const [T];
|
||||
scope 9 (inlined NonNull::<[T]>::from_ref) {
|
||||
let mut _4: *const [T];
|
||||
}
|
||||
}
|
||||
scope 9 (inlined NonNull::<[T]>::cast::<T>) {
|
||||
scope 10 (inlined NonNull::<[T]>::cast::<T>) {
|
||||
let mut _5: *const T;
|
||||
scope 10 (inlined NonNull::<[T]>::as_ptr) {
|
||||
scope 11 (inlined NonNull::<[T]>::as_ptr) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
scope 14 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) {
|
||||
scope 15 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) {
|
||||
}
|
||||
|
||||
bb0: {
|
||||
|
@ -31,25 +31,27 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
|
||||
let _9: *const T;
|
||||
scope 7 {
|
||||
}
|
||||
scope 11 (inlined without_provenance::<T>) {
|
||||
scope 12 (inlined without_provenance::<T>) {
|
||||
}
|
||||
scope 12 (inlined NonNull::<T>::as_ptr) {
|
||||
scope 13 (inlined NonNull::<T>::as_ptr) {
|
||||
}
|
||||
scope 13 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
|
||||
scope 14 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
|
||||
}
|
||||
}
|
||||
scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) {
|
||||
let mut _4: *const [T];
|
||||
scope 9 (inlined NonNull::<[T]>::from_ref) {
|
||||
let mut _4: *const [T];
|
||||
}
|
||||
}
|
||||
scope 9 (inlined NonNull::<[T]>::cast::<T>) {
|
||||
scope 10 (inlined NonNull::<[T]>::cast::<T>) {
|
||||
let mut _5: *const T;
|
||||
scope 10 (inlined NonNull::<[T]>::as_ptr) {
|
||||
scope 11 (inlined NonNull::<[T]>::as_ptr) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
scope 14 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) {
|
||||
scope 15 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) {
|
||||
}
|
||||
|
||||
bb0: {
|
||||
|
@ -18,7 +18,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
|
||||
scope 2 {
|
||||
debug x => _17;
|
||||
}
|
||||
scope 17 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
|
||||
scope 18 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
|
||||
let mut _14: &mut std::slice::Iter<'_, T>;
|
||||
}
|
||||
}
|
||||
@ -34,29 +34,31 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
|
||||
let _9: *const T;
|
||||
scope 7 {
|
||||
}
|
||||
scope 11 (inlined without_provenance::<T>) {
|
||||
scope 12 (inlined without_provenance::<T>) {
|
||||
}
|
||||
scope 12 (inlined NonNull::<T>::as_ptr) {
|
||||
scope 13 (inlined NonNull::<T>::as_ptr) {
|
||||
}
|
||||
scope 13 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
|
||||
scope 14 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
|
||||
}
|
||||
}
|
||||
scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) {
|
||||
let mut _4: *const [T];
|
||||
scope 9 (inlined NonNull::<[T]>::from_ref) {
|
||||
let mut _4: *const [T];
|
||||
}
|
||||
}
|
||||
scope 9 (inlined NonNull::<[T]>::cast::<T>) {
|
||||
scope 10 (inlined NonNull::<[T]>::cast::<T>) {
|
||||
let mut _5: *const T;
|
||||
scope 10 (inlined NonNull::<[T]>::as_ptr) {
|
||||
scope 11 (inlined NonNull::<[T]>::as_ptr) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
scope 14 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) {
|
||||
scope 15 (inlined Rev::<std::slice::Iter<'_, T>>::new) {
|
||||
scope 15 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) {
|
||||
scope 16 (inlined Rev::<std::slice::Iter<'_, T>>::new) {
|
||||
}
|
||||
}
|
||||
scope 16 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
|
||||
scope 17 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
|
||||
}
|
||||
|
||||
bb0: {
|
||||
|
@ -18,7 +18,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
|
||||
scope 2 {
|
||||
debug x => _17;
|
||||
}
|
||||
scope 17 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
|
||||
scope 18 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
|
||||
let mut _14: &mut std::slice::Iter<'_, T>;
|
||||
}
|
||||
}
|
||||
@ -34,29 +34,31 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
|
||||
let _9: *const T;
|
||||
scope 7 {
|
||||
}
|
||||
scope 11 (inlined without_provenance::<T>) {
|
||||
scope 12 (inlined without_provenance::<T>) {
|
||||
}
|
||||
scope 12 (inlined NonNull::<T>::as_ptr) {
|
||||
scope 13 (inlined NonNull::<T>::as_ptr) {
|
||||
}
|
||||
scope 13 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
|
||||
scope 14 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
|
||||
}
|
||||
}
|
||||
scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) {
|
||||
let mut _4: *const [T];
|
||||
scope 9 (inlined NonNull::<[T]>::from_ref) {
|
||||
let mut _4: *const [T];
|
||||
}
|
||||
}
|
||||
scope 9 (inlined NonNull::<[T]>::cast::<T>) {
|
||||
scope 10 (inlined NonNull::<[T]>::cast::<T>) {
|
||||
let mut _5: *const T;
|
||||
scope 10 (inlined NonNull::<[T]>::as_ptr) {
|
||||
scope 11 (inlined NonNull::<[T]>::as_ptr) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
scope 14 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) {
|
||||
scope 15 (inlined Rev::<std::slice::Iter<'_, T>>::new) {
|
||||
scope 15 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) {
|
||||
scope 16 (inlined Rev::<std::slice::Iter<'_, T>>::new) {
|
||||
}
|
||||
}
|
||||
scope 16 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
|
||||
scope 17 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
|
||||
}
|
||||
|
||||
bb0: {
|
||||
|
27
tests/rustdoc/dyn-compatibility.rs
Normal file
27
tests/rustdoc/dyn-compatibility.rs
Normal file
@ -0,0 +1,27 @@
|
||||
#![crate_name = "foo"]
|
||||
|
||||
//@ has 'foo/trait.DynIncompatible.html'
|
||||
//@ has - '//*[@class="dyn-compatibility-info"]' 'This trait is not dyn compatible.'
|
||||
//@ has - '//*[@id="dyn-compatibility"]' 'Dyn Compatibility'
|
||||
pub trait DynIncompatible {
|
||||
fn foo() -> Self;
|
||||
}
|
||||
|
||||
//@ has 'foo/trait.DynIncompatible2.html'
|
||||
//@ has - '//*[@class="dyn-compatibility-info"]' 'This trait is not dyn compatible.'
|
||||
//@ has - '//*[@id="dyn-compatibility"]' 'Dyn Compatibility'
|
||||
pub trait DynIncompatible2<T> {
|
||||
fn foo(i: T);
|
||||
}
|
||||
|
||||
//@ has 'foo/trait.DynCompatible.html'
|
||||
//@ !has - '//*[@class="dyn-compatibility-info"]' ''
|
||||
//@ !has - '//*[@id="dyn-compatibility"]' ''
|
||||
pub trait DynCompatible {
|
||||
fn foo(&self);
|
||||
}
|
||||
|
||||
//@ has 'foo/struct.Foo.html'
|
||||
//@ count - '//*[@class="dyn-compatibility-info"]' 0
|
||||
//@ count - '//*[@id="dyn-compatibility"]' 0
|
||||
pub struct Foo;
|
@ -14,7 +14,7 @@
|
||||
//@ has - '//*[@class="sidebar-elems"]//section//a' 'Output'
|
||||
//@ has - '//div[@class="sidebar-elems"]//h3/a[@href="#provided-associated-types"]' 'Provided Associated Types'
|
||||
//@ has - '//*[@class="sidebar-elems"]//section//a' 'Extra'
|
||||
//@ has - '//div[@class="sidebar-elems"]//h3/a[@href="#object-safety"]' 'Object Safety'
|
||||
//@ has - '//div[@class="sidebar-elems"]//h3/a[@href="#dyn-compatibility"]' 'Dyn Compatibility'
|
||||
pub trait Foo {
|
||||
const FOO: usize;
|
||||
const BAR: u32 = 0;
|
||||
@ -25,9 +25,9 @@ fn foo() {}
|
||||
fn bar() -> Self::Output;
|
||||
}
|
||||
|
||||
//@ has foo/trait.Safe.html
|
||||
//@ has foo/trait.DynCompatible.html
|
||||
//@ !has - '//div[@class="sidebar-elems"]//h3/a[@href="#object-safety"]' ''
|
||||
pub trait Safe {
|
||||
pub trait DynCompatible {
|
||||
fn access(&self);
|
||||
}
|
||||
|
||||
|
@ -1,27 +0,0 @@
|
||||
#![crate_name = "foo"]
|
||||
|
||||
//@ has 'foo/trait.Unsafe.html'
|
||||
//@ has - '//*[@class="object-safety-info"]' 'This trait is not object safe.'
|
||||
//@ has - '//*[@id="object-safety"]' 'Object Safety'
|
||||
pub trait Unsafe {
|
||||
fn foo() -> Self;
|
||||
}
|
||||
|
||||
//@ has 'foo/trait.Unsafe2.html'
|
||||
//@ has - '//*[@class="object-safety-info"]' 'This trait is not object safe.'
|
||||
//@ has - '//*[@id="object-safety"]' 'Object Safety'
|
||||
pub trait Unsafe2<T> {
|
||||
fn foo(i: T);
|
||||
}
|
||||
|
||||
//@ has 'foo/trait.Safe.html'
|
||||
//@ !has - '//*[@class="object-safety-info"]' ''
|
||||
//@ !has - '//*[@id="object-safety"]' ''
|
||||
pub trait Safe {
|
||||
fn foo(&self);
|
||||
}
|
||||
|
||||
//@ has 'foo/struct.Foo.html'
|
||||
//@ count - '//*[@class="object-safety-info"]' 0
|
||||
//@ count - '//*[@id="object-safety"]' 0
|
||||
pub struct Foo;
|
@ -11,13 +11,6 @@ help: consider mutably borrowing here
|
||||
LL | for item in &mut *things { *item = 0 }
|
||||
| ++++
|
||||
|
||||
error[E0614]: type `<dyn Iterator<Item = &'a mut u8> as IntoIterator>::Item` cannot be dereferenced
|
||||
--> $DIR/issue-20605.rs:6:27
|
||||
|
|
||||
LL | for item in *things { *item = 0 }
|
||||
| ^^^^^
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0277, E0614.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
@ -4,12 +4,7 @@
|
||||
|
||||
fn changer<'a>(mut things: Box<dyn Iterator<Item=&'a mut u8>>) {
|
||||
for item in *things { *item = 0 }
|
||||
//[current]~^ ERROR `dyn Iterator<Item = &'a mut u8>` is not an iterator
|
||||
//[next]~^^ ERROR `dyn Iterator<Item = &'a mut u8>` is not an iterator
|
||||
//[next]~| ERROR type `<dyn Iterator<Item = &'a mut u8> as IntoIterator>::Item` cannot be dereferenced
|
||||
|
||||
// FIXME(-Znext-solver): these error messages are horrible and have to be
|
||||
// improved before we stabilize the new solver.
|
||||
//~^ ERROR `dyn Iterator<Item = &'a mut u8>` is not an iterator
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0283]: type annotations needed
|
||||
--> $DIR/ambig-hr-projection-issue-93340.rs:16:5
|
||||
--> $DIR/ambig-hr-projection-issue-93340.rs:17:5
|
||||
|
|
||||
LL | cmp_eq
|
||||
| ^^^^^^ cannot infer type of the type parameter `A` declared on the function `cmp_eq`
|
||||
@ -15,6 +15,16 @@ help: consider specifying the generic arguments
|
||||
LL | cmp_eq::<A, B, O>
|
||||
| +++++++++++
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
error[E0277]: expected a `Fn(<A as Scalar>::RefType<'_>, <B as Scalar>::RefType<'_>)` closure, found `for<'a, 'b> fn(<O as Scalar>::RefType<'a>, <_ as Scalar>::RefType<'b>) -> O {cmp_eq::<O, _, O>}`
|
||||
--> $DIR/ambig-hr-projection-issue-93340.rs:14:1
|
||||
|
|
||||
LL | / fn build_expression<A: Scalar, B: Scalar, O: Scalar>(
|
||||
LL | | ) -> impl Fn(A::RefType<'_>, B::RefType<'_>) -> O {
|
||||
| |_________________________________________________^ expected an `Fn(<A as Scalar>::RefType<'_>, <B as Scalar>::RefType<'_>)` closure, found `for<'a, 'b> fn(<O as Scalar>::RefType<'a>, <_ as Scalar>::RefType<'b>) -> O {cmp_eq::<O, _, O>}`
|
||||
|
|
||||
= help: the trait `for<'a, 'b> Fn(<A as Scalar>::RefType<'a>, <B as Scalar>::RefType<'b>)` is not implemented for fn item `for<'a, 'b> fn(<O as Scalar>::RefType<'a>, <_ as Scalar>::RefType<'b>) -> O {cmp_eq::<O, _, O>}`
|
||||
|
||||
For more information about this error, try `rustc --explain E0283`.
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0277, E0283.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0283]: type annotations needed
|
||||
--> $DIR/ambig-hr-projection-issue-93340.rs:16:5
|
||||
--> $DIR/ambig-hr-projection-issue-93340.rs:17:5
|
||||
|
|
||||
LL | cmp_eq
|
||||
| ^^^^^^ cannot infer type of the type parameter `A` declared on the function `cmp_eq`
|
||||
|
@ -13,6 +13,7 @@ fn cmp_eq<'a, 'b, A: Scalar, B: Scalar, O: Scalar>(a: A::RefType<'a>, b: B::RefT
|
||||
|
||||
fn build_expression<A: Scalar, B: Scalar, O: Scalar>(
|
||||
) -> impl Fn(A::RefType<'_>, B::RefType<'_>) -> O {
|
||||
//[next]~^^ expected a `Fn(<A as Scalar>::RefType<'_>, <B as Scalar>::RefType<'_>)` closure
|
||||
cmp_eq
|
||||
//~^ ERROR type annotations needed
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ trait Overlap<T> {}
|
||||
impl<T> Overlap<T> for T {}
|
||||
|
||||
impl<T> Overlap<for<'a> fn(&'a (), Assoc<'a, T>)> for T {}
|
||||
//~^ ERROR conflicting implementations of trait `Overlap<for<'a> fn(&'a (), _)>`
|
||||
//~^ ERROR the trait bound `for<'a> T: ToUnit<'a>` is not satisfied
|
||||
//~| ERROR the trait bound `for<'a> T: ToUnit<'a>` is not satisfied
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,18 +1,26 @@
|
||||
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit), .. }
|
||||
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit), .. }
|
||||
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit), .. }
|
||||
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit), .. }
|
||||
error[E0119]: conflicting implementations of trait `Overlap<for<'a> fn(&'a (), _)>` for type `for<'a> fn(&'a (), _)`
|
||||
--> $DIR/structually-relate-aliases.rs:13:1
|
||||
error[E0277]: the trait bound `for<'a> T: ToUnit<'a>` is not satisfied
|
||||
--> $DIR/structually-relate-aliases.rs:13:36
|
||||
|
|
||||
LL | impl<T> Overlap<T> for T {}
|
||||
| ------------------------ first implementation here
|
||||
LL |
|
||||
LL | impl<T> Overlap<for<'a> fn(&'a (), Assoc<'a, T>)> for T {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a> fn(&'a (), _)`
|
||||
| ^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `T`
|
||||
|
|
||||
= note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details
|
||||
help: consider restricting type parameter `T`
|
||||
|
|
||||
LL | impl<T: for<'a> ToUnit<'a>> Overlap<for<'a> fn(&'a (), Assoc<'a, T>)> for T {}
|
||||
| ++++++++++++++++++++
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
error[E0277]: the trait bound `for<'a> T: ToUnit<'a>` is not satisfied
|
||||
--> $DIR/structually-relate-aliases.rs:13:17
|
||||
|
|
||||
LL | impl<T> Overlap<for<'a> fn(&'a (), Assoc<'a, T>)> for T {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `T`
|
||||
|
|
||||
help: consider restricting type parameter `T`
|
||||
|
|
||||
LL | impl<T: for<'a> ToUnit<'a>> Overlap<for<'a> fn(&'a (), Assoc<'a, T>)> for T {}
|
||||
| ++++++++++++++++++++
|
||||
|
||||
For more information about this error, try `rustc --explain E0119`.
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
@ -14,6 +14,8 @@ trait Foo {}
|
||||
// `usize: Foo` doesn't hold. Therefore we ICE, because we don't expect to still
|
||||
// encounter weak types in `assemble_alias_bound_candidates_recur`.
|
||||
fn hello(_: W<A<usize>>) {}
|
||||
//~^ ERROR the size for values of type `A<usize>` cannot be known at compilation time
|
||||
//~^ ERROR the trait bound `usize: Foo` is not satisfied
|
||||
//~| ERROR the trait bound `usize: Foo` is not satisfied
|
||||
//~| ERROR the trait bound `usize: Foo` is not satisfied
|
||||
|
||||
fn main() {}
|
||||
|
@ -7,14 +7,42 @@ LL | #![feature(lazy_type_alias)]
|
||||
= note: see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
error[E0277]: the size for values of type `A<usize>` cannot be known at compilation time
|
||||
error[E0277]: the trait bound `usize: Foo` is not satisfied
|
||||
--> $DIR/alias-bounds-when-not-wf.rs:16:13
|
||||
|
|
||||
LL | fn hello(_: W<A<usize>>) {}
|
||||
| ^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
| ^^^^^^^^^^^ the trait `Foo` is not implemented for `usize`
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `A<usize>`
|
||||
help: this trait has no implementations, consider adding one
|
||||
--> $DIR/alias-bounds-when-not-wf.rs:6:1
|
||||
|
|
||||
LL | trait Foo {}
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error; 1 warning emitted
|
||||
error[E0277]: the trait bound `usize: Foo` is not satisfied
|
||||
--> $DIR/alias-bounds-when-not-wf.rs:16:10
|
||||
|
|
||||
LL | fn hello(_: W<A<usize>>) {}
|
||||
| ^ the trait `Foo` is not implemented for `usize`
|
||||
|
|
||||
help: this trait has no implementations, consider adding one
|
||||
--> $DIR/alias-bounds-when-not-wf.rs:6:1
|
||||
|
|
||||
LL | trait Foo {}
|
||||
| ^^^^^^^^^
|
||||
|
||||
error[E0277]: the trait bound `usize: Foo` is not satisfied
|
||||
--> $DIR/alias-bounds-when-not-wf.rs:16:1
|
||||
|
|
||||
LL | fn hello(_: W<A<usize>>) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `usize`
|
||||
|
|
||||
help: this trait has no implementations, consider adding one
|
||||
--> $DIR/alias-bounds-when-not-wf.rs:6:1
|
||||
|
|
||||
LL | trait Foo {}
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: aborting due to 3 previous errors; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
@ -4,19 +4,6 @@ error[E0282]: type annotations needed
|
||||
LL | foo(false).next().unwrap();
|
||||
| ^^^^^^^^^^ cannot infer type
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/method-resolution4.rs:16:5
|
||||
|
|
||||
LL | fn foo(b: bool) -> impl Iterator<Item = ()> {
|
||||
| ------------------------ the expected opaque type
|
||||
...
|
||||
LL | std::iter::empty()
|
||||
| ^^^^^^^^^^^^^^^^^^ types differ
|
||||
|
|
||||
= note: expected opaque type `impl Iterator<Item = ()>`
|
||||
found struct `std::iter::Empty<_>`
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0282, E0308.
|
||||
For more information about an error, try `rustc --explain E0282`.
|
||||
For more information about this error, try `rustc --explain E0282`.
|
||||
|
@ -14,7 +14,6 @@ fn foo(b: bool) -> impl Iterator<Item = ()> {
|
||||
//[next]~^ type annotations needed
|
||||
}
|
||||
std::iter::empty()
|
||||
//[next]~^ mismatched types
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/recursive-coroutine-boxed.rs:15:23
|
||||
--> $DIR/recursive-coroutine-boxed.rs:14:23
|
||||
|
|
||||
LL | let mut gen = Box::pin(foo());
|
||||
| ^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `Box`
|
||||
@ -12,29 +12,6 @@ help: consider specifying the generic argument
|
||||
LL | let mut gen = Box::<T>::pin(foo());
|
||||
| +++++
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/recursive-coroutine-boxed.rs:14:18
|
||||
|
|
||||
LL | fn foo() -> impl Coroutine<Yield = (), Return = ()> {
|
||||
| ---------------------------------------
|
||||
| |
|
||||
| the expected opaque type
|
||||
| expected `impl Coroutine<Yield = (), Return = ()>` because of return type
|
||||
...
|
||||
LL | #[coroutine] || {
|
||||
| __________________^
|
||||
LL | | let mut gen = Box::pin(foo());
|
||||
LL | |
|
||||
LL | | let mut r = gen.as_mut().resume(());
|
||||
... |
|
||||
LL | | }
|
||||
LL | | }
|
||||
| |_____^ types differ
|
||||
|
|
||||
= note: expected opaque type `impl Coroutine<Yield = (), Return = ()>`
|
||||
found coroutine `{coroutine@$DIR/recursive-coroutine-boxed.rs:14:18: 14:20}`
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0282, E0308.
|
||||
For more information about an error, try `rustc --explain E0282`.
|
||||
For more information about this error, try `rustc --explain E0282`.
|
||||
|
@ -10,8 +10,7 @@ fn foo() -> impl Coroutine<Yield = (), Return = ()> {
|
||||
// FIXME(-Znext-solver): this fails with a mismatched types as the
|
||||
// hidden type of the opaque ends up as {type error}. We should not
|
||||
// emit errors for such goals.
|
||||
|
||||
#[coroutine] || { //[next]~ ERROR mismatched types
|
||||
#[coroutine] || {
|
||||
let mut gen = Box::pin(foo());
|
||||
//[next]~^ ERROR type annotations needed
|
||||
let mut r = gen.as_mut().resume(());
|
||||
|
@ -1,26 +1,35 @@
|
||||
error[E0271]: type mismatch resolving `impl Trait <: dyn Trait`
|
||||
--> $DIR/unsized_coercion.rs:14:17
|
||||
error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time
|
||||
--> $DIR/unsized_coercion.rs:15:17
|
||||
|
|
||||
LL | let x = hello();
|
||||
| ^^^^^^^ types differ
|
||||
| ^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `dyn Trait`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/unsized_coercion.rs:18:14
|
||||
--> $DIR/unsized_coercion.rs:19:5
|
||||
|
|
||||
LL | fn hello() -> Box<impl Trait> {
|
||||
| ---------- the expected opaque type
|
||||
| ---------------
|
||||
| | |
|
||||
| | the expected opaque type
|
||||
| expected `Box<impl Trait>` because of return type
|
||||
...
|
||||
LL | Box::new(1u32)
|
||||
| -------- ^^^^ types differ
|
||||
| |
|
||||
| arguments to this function are incorrect
|
||||
| ^^^^^^^^^^^^^^ types differ
|
||||
|
|
||||
= note: expected opaque type `impl Trait`
|
||||
found type `u32`
|
||||
note: associated function defined here
|
||||
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
|
||||
= note: expected struct `Box<impl Trait>`
|
||||
found struct `Box<u32>`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time
|
||||
--> $DIR/unsized_coercion.rs:12:1
|
||||
|
|
||||
LL | fn hello() -> Box<impl Trait> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `dyn Trait`
|
||||
|
||||
Some errors have detailed explanations: E0271, E0308.
|
||||
For more information about an error, try `rustc --explain E0271`.
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0277, E0308.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
||||
|
@ -10,9 +10,10 @@ trait Trait {}
|
||||
impl Trait for u32 {}
|
||||
|
||||
fn hello() -> Box<impl Trait> {
|
||||
//[next]~^ ERROR the size for values of type `dyn Trait` cannot be known at compilation time
|
||||
if true {
|
||||
let x = hello();
|
||||
//[next]~^ ERROR: type mismatch resolving `impl Trait <: dyn Trait`
|
||||
//[next]~^ ERROR: the size for values of type `dyn Trait` cannot be known at compilation time
|
||||
let y: Box<dyn Trait> = x;
|
||||
}
|
||||
Box::new(1u32) //[next]~ ERROR: mismatched types
|
||||
|
@ -1,38 +1,35 @@
|
||||
error[E0271]: type mismatch resolving `impl Trait + ?Sized <: dyn Send`
|
||||
--> $DIR/unsized_coercion3.rs:13:17
|
||||
error[E0277]: the trait bound `dyn Send: Trait` is not satisfied
|
||||
--> $DIR/unsized_coercion3.rs:14:17
|
||||
|
|
||||
LL | let x = hello();
|
||||
| ^^^^^^^ types differ
|
||||
| ^^^^^^^ the trait `Trait` is not implemented for `dyn Send`
|
||||
|
|
||||
= help: the trait `Trait` is implemented for `u32`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/unsized_coercion3.rs:18:14
|
||||
--> $DIR/unsized_coercion3.rs:19:5
|
||||
|
|
||||
LL | fn hello() -> Box<impl Trait + ?Sized> {
|
||||
| ------------------- the expected opaque type
|
||||
| ------------------------
|
||||
| | |
|
||||
| | the expected opaque type
|
||||
| expected `Box<impl Trait + ?Sized>` because of return type
|
||||
...
|
||||
LL | Box::new(1u32)
|
||||
| -------- ^^^^ types differ
|
||||
| |
|
||||
| arguments to this function are incorrect
|
||||
| ^^^^^^^^^^^^^^ types differ
|
||||
|
|
||||
= note: expected opaque type `impl Trait + ?Sized`
|
||||
found type `u32`
|
||||
note: associated function defined here
|
||||
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
|
||||
= note: expected struct `Box<impl Trait + ?Sized>`
|
||||
found struct `Box<u32>`
|
||||
|
||||
error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time
|
||||
--> $DIR/unsized_coercion3.rs:18:14
|
||||
error[E0277]: the trait bound `dyn Send: Trait` is not satisfied
|
||||
--> $DIR/unsized_coercion3.rs:11:1
|
||||
|
|
||||
LL | Box::new(1u32)
|
||||
| -------- ^^^^ doesn't have a size known at compile-time
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
LL | fn hello() -> Box<impl Trait + ?Sized> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `dyn Send`
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `impl Trait + ?Sized`
|
||||
note: required by a bound in `Box::<T>::new`
|
||||
--> $SRC_DIR/alloc/src/boxed.rs:LL:COL
|
||||
= help: the trait `Trait` is implemented for `u32`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0271, E0277, E0308.
|
||||
For more information about an error, try `rustc --explain E0271`.
|
||||
Some errors have detailed explanations: E0277, E0308.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0277]: the size for values of type `impl Trait + ?Sized` cannot be known at compilation time
|
||||
--> $DIR/unsized_coercion3.rs:15:32
|
||||
--> $DIR/unsized_coercion3.rs:16:32
|
||||
|
|
||||
LL | let y: Box<dyn Send> = x;
|
||||
| ^ doesn't have a size known at compile-time
|
||||
|
@ -9,15 +9,15 @@ trait Trait {}
|
||||
impl Trait for u32 {}
|
||||
|
||||
fn hello() -> Box<impl Trait + ?Sized> {
|
||||
//[next]~^ ERROR: the trait bound `dyn Send: Trait` is not satisfied
|
||||
if true {
|
||||
let x = hello();
|
||||
//[next]~^ ERROR: type mismatch resolving `impl Trait + ?Sized <: dyn Send`
|
||||
//[next]~^ ERROR: the trait bound `dyn Send: Trait` is not satisfied
|
||||
let y: Box<dyn Send> = x;
|
||||
//[old]~^ ERROR: the size for values of type `impl Trait + ?Sized` cannot be know
|
||||
}
|
||||
Box::new(1u32)
|
||||
//[next]~^ ERROR: mismatched types
|
||||
//[next]~| ERROR: the size for values of type `impl Trait + ?Sized` cannot be know
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,11 +1,11 @@
|
||||
error: crate `NonSnakeCase` should have a snake case name
|
||||
--> $DIR/lint-non-snake-case-crate.rs:25:18
|
||||
--> $DIR/lint-non-snake-case-crate.rs:29:18
|
||||
|
|
||||
LL | #![crate_name = "NonSnakeCase"]
|
||||
| ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/lint-non-snake-case-crate.rs:27:9
|
||||
--> $DIR/lint-non-snake-case-crate.rs:31:9
|
||||
|
|
||||
LL | #![deny(non_snake_case)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
@ -1,11 +1,11 @@
|
||||
error: crate `NonSnakeCase` should have a snake case name
|
||||
--> $DIR/lint-non-snake-case-crate.rs:25:18
|
||||
--> $DIR/lint-non-snake-case-crate.rs:29:18
|
||||
|
|
||||
LL | #![crate_name = "NonSnakeCase"]
|
||||
| ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/lint-non-snake-case-crate.rs:27:9
|
||||
--> $DIR/lint-non-snake-case-crate.rs:31:9
|
||||
|
|
||||
LL | #![deny(non_snake_case)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
@ -1,11 +1,11 @@
|
||||
error: crate `NonSnakeCase` should have a snake case name
|
||||
--> $DIR/lint-non-snake-case-crate.rs:25:18
|
||||
--> $DIR/lint-non-snake-case-crate.rs:29:18
|
||||
|
|
||||
LL | #![crate_name = "NonSnakeCase"]
|
||||
| ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/lint-non-snake-case-crate.rs:27:9
|
||||
--> $DIR/lint-non-snake-case-crate.rs:31:9
|
||||
|
|
||||
LL | #![deny(non_snake_case)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
@ -1,11 +1,11 @@
|
||||
error: crate `NonSnakeCase` should have a snake case name
|
||||
--> $DIR/lint-non-snake-case-crate.rs:25:18
|
||||
--> $DIR/lint-non-snake-case-crate.rs:29:18
|
||||
|
|
||||
LL | #![crate_name = "NonSnakeCase"]
|
||||
| ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/lint-non-snake-case-crate.rs:27:9
|
||||
--> $DIR/lint-non-snake-case-crate.rs:31:9
|
||||
|
|
||||
LL | #![deny(non_snake_case)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
@ -1,11 +1,11 @@
|
||||
error: crate `NonSnakeCase` should have a snake case name
|
||||
--> $DIR/lint-non-snake-case-crate.rs:25:18
|
||||
--> $DIR/lint-non-snake-case-crate.rs:29:18
|
||||
|
|
||||
LL | #![crate_name = "NonSnakeCase"]
|
||||
| ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/lint-non-snake-case-crate.rs:27:9
|
||||
--> $DIR/lint-non-snake-case-crate.rs:31:9
|
||||
|
|
||||
LL | #![deny(non_snake_case)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
@ -22,6 +22,10 @@
|
||||
//@[rlib_] compile-flags: --crate-type=rlib
|
||||
//@[staticlib_] compile-flags: --crate-type=staticlib
|
||||
|
||||
// The compiler may emit a warning that causes stderr output
|
||||
// that contains a warning this test does not wish to check.
|
||||
//@[proc_macro_] needs-unwind
|
||||
|
||||
#![crate_name = "NonSnakeCase"]
|
||||
//[cdylib_,dylib_,lib_,proc_macro_,rlib_,staticlib_]~^ ERROR crate `NonSnakeCase` should have a snake case name
|
||||
#![deny(non_snake_case)]
|
||||
|
@ -1,11 +1,11 @@
|
||||
error: crate `NonSnakeCase` should have a snake case name
|
||||
--> $DIR/lint-non-snake-case-crate.rs:25:18
|
||||
--> $DIR/lint-non-snake-case-crate.rs:29:18
|
||||
|
|
||||
LL | #![crate_name = "NonSnakeCase"]
|
||||
| ^^^^^^^^^^^^ help: convert the identifier to snake case: `non_snake_case`
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/lint-non-snake-case-crate.rs:27:9
|
||||
--> $DIR/lint-non-snake-case-crate.rs:31:9
|
||||
|
|
||||
LL | #![deny(non_snake_case)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Regression test for MIR inlining with -Zalways-encode-mir enabled in the auxiliary crate.
|
||||
// Previously we inlined function not eligible for inlining which lead to linking error:
|
||||
// undefined reference to `internal::S'
|
||||
// undefined reference to `internal::S`
|
||||
//
|
||||
//@ aux-build:internal.rs
|
||||
//@ build-pass
|
||||
|
@ -1,57 +0,0 @@
|
||||
//@ edition: 2021
|
||||
//@ run-rustfix
|
||||
//@ rustfix-only-machine-applicable
|
||||
//@ aux-build:match_ergonomics_2024_macros.rs
|
||||
#![feature(mut_ref, ref_pat_eat_one_layer_2024)]
|
||||
#![allow(incomplete_features, unused)]
|
||||
#![deny(rust_2024_incompatible_pat)]
|
||||
|
||||
extern crate match_ergonomics_2024_macros;
|
||||
|
||||
struct Foo(u8);
|
||||
|
||||
fn main() {
|
||||
let &Foo(mut a) = &Foo(0);
|
||||
//~^ ERROR: the semantics of this pattern will change in edition 2024
|
||||
a = 42;
|
||||
|
||||
let &mut Foo(mut a) = &mut Foo(0);
|
||||
//~^ ERROR: the semantics of this pattern will change in edition 2024
|
||||
a = 42;
|
||||
|
||||
if let &&&&&Some(&_) = &&&&&Some(&0u8) {}
|
||||
//~^ ERROR: the semantics of this pattern will change in edition 2024
|
||||
|
||||
if let &&&&&Some(&mut _) = &&&&&Some(&mut 0u8) {}
|
||||
//~^ ERROR: the semantics of this pattern will change in edition 2024
|
||||
|
||||
if let &&&&&mut Some(&_) = &&&&&mut Some(&0u8) {}
|
||||
//~^ ERROR: the semantics of this pattern will change in edition 2024
|
||||
|
||||
if let &mut Some(&mut Some(&mut Some(_))) = &mut Some(&mut Some(&mut Some(0u8))) {}
|
||||
//~^ ERROR: the semantics of this pattern will change in edition 2024
|
||||
|
||||
if let &mut Some(&mut Some(&mut Some(ref mut _a))) = &mut Some(&mut Some(&mut Some(0u8))) {}
|
||||
//~^ ERROR: the semantics of this pattern will change in edition 2024
|
||||
|
||||
struct Struct {
|
||||
a: u32,
|
||||
b: u32,
|
||||
c: u32,
|
||||
}
|
||||
let s = Struct { a: 0, b: 0, c: 0 };
|
||||
let &Struct { ref a, mut b, ref c } = &s;
|
||||
//~^ ERROR: the semantics of this pattern will change in edition 2024
|
||||
|
||||
#[warn(rust_2024_incompatible_pat)]
|
||||
match &(Some(0), Some(0)) {
|
||||
// The two patterns are the same syntactically, but because they're defined in different
|
||||
// editions they don't mean the same thing.
|
||||
(Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!(_y)) => {
|
||||
//~^ WARN: the semantics of this pattern will change in edition 2024
|
||||
_x = 4;
|
||||
_y = &7;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
//@ edition: 2021
|
||||
//@ run-rustfix
|
||||
//@ rustfix-only-machine-applicable
|
||||
//@ aux-build:match_ergonomics_2024_macros.rs
|
||||
#![feature(mut_ref, ref_pat_eat_one_layer_2024)]
|
||||
#![allow(incomplete_features, unused)]
|
||||
#![deny(rust_2024_incompatible_pat)]
|
||||
|
||||
extern crate match_ergonomics_2024_macros;
|
||||
|
||||
struct Foo(u8);
|
||||
|
||||
fn main() {
|
||||
let Foo(mut a) = &Foo(0);
|
||||
//~^ ERROR: the semantics of this pattern will change in edition 2024
|
||||
a = 42;
|
||||
|
||||
let Foo(mut a) = &mut Foo(0);
|
||||
//~^ ERROR: the semantics of this pattern will change in edition 2024
|
||||
a = 42;
|
||||
|
||||
if let Some(&_) = &&&&&Some(&0u8) {}
|
||||
//~^ ERROR: the semantics of this pattern will change in edition 2024
|
||||
|
||||
if let Some(&mut _) = &&&&&Some(&mut 0u8) {}
|
||||
//~^ ERROR: the semantics of this pattern will change in edition 2024
|
||||
|
||||
if let Some(&_) = &&&&&mut Some(&0u8) {}
|
||||
//~^ ERROR: the semantics of this pattern will change in edition 2024
|
||||
|
||||
if let Some(&mut Some(Some(_))) = &mut Some(&mut Some(&mut Some(0u8))) {}
|
||||
//~^ ERROR: the semantics of this pattern will change in edition 2024
|
||||
|
||||
if let Some(&mut Some(Some(_a))) = &mut Some(&mut Some(&mut Some(0u8))) {}
|
||||
//~^ ERROR: the semantics of this pattern will change in edition 2024
|
||||
|
||||
struct Struct {
|
||||
a: u32,
|
||||
b: u32,
|
||||
c: u32,
|
||||
}
|
||||
let s = Struct { a: 0, b: 0, c: 0 };
|
||||
let Struct { a, mut b, c } = &s;
|
||||
//~^ ERROR: the semantics of this pattern will change in edition 2024
|
||||
|
||||
#[warn(rust_2024_incompatible_pat)]
|
||||
match &(Some(0), Some(0)) {
|
||||
// The two patterns are the same syntactically, but because they're defined in different
|
||||
// editions they don't mean the same thing.
|
||||
(Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!(_y)) => {
|
||||
//~^ WARN: the semantics of this pattern will change in edition 2024
|
||||
_x = 4;
|
||||
_y = &7;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
@ -1,97 +0,0 @@
|
||||
error: the semantics of this pattern will change in edition 2024
|
||||
--> $DIR/match_ergonomics_2024.rs:14:9
|
||||
|
|
||||
LL | let Foo(mut a) = &Foo(0);
|
||||
| -^^^^^^^^^
|
||||
| |
|
||||
| help: desugar the match ergonomics: `&`
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/match_ergonomics_2024.rs:7:9
|
||||
|
|
||||
LL | #![deny(rust_2024_incompatible_pat)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: the semantics of this pattern will change in edition 2024
|
||||
--> $DIR/match_ergonomics_2024.rs:18:9
|
||||
|
|
||||
LL | let Foo(mut a) = &mut Foo(0);
|
||||
| -^^^^^^^^^
|
||||
| |
|
||||
| help: desugar the match ergonomics: `&mut`
|
||||
|
||||
error: the semantics of this pattern will change in edition 2024
|
||||
--> $DIR/match_ergonomics_2024.rs:22:12
|
||||
|
|
||||
LL | if let Some(&_) = &&&&&Some(&0u8) {}
|
||||
| -^^^^^^^
|
||||
| |
|
||||
| help: desugar the match ergonomics: `&&&&&`
|
||||
|
||||
error: the semantics of this pattern will change in edition 2024
|
||||
--> $DIR/match_ergonomics_2024.rs:25:12
|
||||
|
|
||||
LL | if let Some(&mut _) = &&&&&Some(&mut 0u8) {}
|
||||
| -^^^^^^^^^^^
|
||||
| |
|
||||
| help: desugar the match ergonomics: `&&&&&`
|
||||
|
||||
error: the semantics of this pattern will change in edition 2024
|
||||
--> $DIR/match_ergonomics_2024.rs:28:12
|
||||
|
|
||||
LL | if let Some(&_) = &&&&&mut Some(&0u8) {}
|
||||
| -^^^^^^^
|
||||
| |
|
||||
| help: desugar the match ergonomics: `&&&&&mut`
|
||||
|
||||
error: the semantics of this pattern will change in edition 2024
|
||||
--> $DIR/match_ergonomics_2024.rs:31:12
|
||||
|
|
||||
LL | if let Some(&mut Some(Some(_))) = &mut Some(&mut Some(&mut Some(0u8))) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: desugar the match ergonomics
|
||||
|
|
||||
LL | if let &mut Some(&mut Some(&mut Some(_))) = &mut Some(&mut Some(&mut Some(0u8))) {}
|
||||
| ++++ ++++
|
||||
|
||||
error: the semantics of this pattern will change in edition 2024
|
||||
--> $DIR/match_ergonomics_2024.rs:34:12
|
||||
|
|
||||
LL | if let Some(&mut Some(Some(_a))) = &mut Some(&mut Some(&mut Some(0u8))) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: desugar the match ergonomics
|
||||
|
|
||||
LL | if let &mut Some(&mut Some(&mut Some(ref mut _a))) = &mut Some(&mut Some(&mut Some(0u8))) {}
|
||||
| ++++ ++++ +++++++
|
||||
|
||||
error: the semantics of this pattern will change in edition 2024
|
||||
--> $DIR/match_ergonomics_2024.rs:43:9
|
||||
|
|
||||
LL | let Struct { a, mut b, c } = &s;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: desugar the match ergonomics
|
||||
|
|
||||
LL | let &Struct { ref a, mut b, ref c } = &s;
|
||||
| + +++ +++
|
||||
|
||||
warning: the semantics of this pattern will change in edition 2024
|
||||
--> $DIR/match_ergonomics_2024.rs:50:9
|
||||
|
|
||||
LL | (Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!(_y)) => {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/match_ergonomics_2024.rs:46:12
|
||||
|
|
||||
LL | #[warn(rust_2024_incompatible_pat)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: desugar the match ergonomics
|
||||
|
|
||||
LL | &(Some(mut _x), match_ergonomics_2024_macros::mixed_edition_pat!(ref _y)) => {
|
||||
| + +++
|
||||
|
||||
error: aborting due to 8 previous errors; 1 warning emitted
|
||||
|
@ -0,0 +1,144 @@
|
||||
//@ edition: 2021
|
||||
//@ run-rustfix
|
||||
//@ rustfix-only-machine-applicable
|
||||
//@ aux-build:migration_lint_macros.rs
|
||||
#![feature(mut_ref)]
|
||||
#![allow(incomplete_features, unused)]
|
||||
#![deny(rust_2024_incompatible_pat)]
|
||||
|
||||
extern crate migration_lint_macros;
|
||||
|
||||
struct Foo<T>(T);
|
||||
|
||||
// Tests type equality in a way that avoids coercing `&&T` to `&T`.
|
||||
trait Eq<T> {}
|
||||
impl<T> Eq<T> for T {}
|
||||
fn assert_type_eq<T, U: Eq<T>>(_: T, _: U) {}
|
||||
|
||||
fn main() {
|
||||
let Foo(x) = &Foo(0);
|
||||
assert_type_eq(x, &0u8);
|
||||
|
||||
let Foo(x) = &mut Foo(0);
|
||||
assert_type_eq(x, &mut 0u8);
|
||||
|
||||
let &Foo(mut x) = &Foo(0);
|
||||
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, 0u8);
|
||||
|
||||
let &mut Foo(mut x) = &mut Foo(0);
|
||||
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, 0u8);
|
||||
|
||||
let &Foo(ref x) = &Foo(0);
|
||||
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, &0u8);
|
||||
|
||||
let &mut Foo(ref x) = &mut Foo(0);
|
||||
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, &0u8);
|
||||
|
||||
let &Foo(x) = &Foo(0);
|
||||
assert_type_eq(x, 0u8);
|
||||
|
||||
let &mut Foo(x) = &mut Foo(0);
|
||||
assert_type_eq(x, 0u8);
|
||||
|
||||
let &Foo(x) = &Foo(&0);
|
||||
assert_type_eq(x, &0u8);
|
||||
|
||||
let &mut Foo(x) = &mut Foo(&0);
|
||||
assert_type_eq(x, &0u8);
|
||||
|
||||
let &Foo(&x) = &Foo(&0);
|
||||
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, 0u8);
|
||||
|
||||
let &Foo(&mut x) = &Foo(&mut 0);
|
||||
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, 0u8);
|
||||
|
||||
let &mut Foo(&x) = &mut Foo(&0);
|
||||
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, 0u8);
|
||||
|
||||
let &mut Foo(&mut x) = &mut Foo(&mut 0);
|
||||
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, 0u8);
|
||||
|
||||
if let Some(x) = &&&&&Some(&0u8) {
|
||||
assert_type_eq(x, &&0u8);
|
||||
}
|
||||
|
||||
if let &&&&&Some(&x) = &&&&&Some(&0u8) {
|
||||
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, 0u8);
|
||||
}
|
||||
|
||||
if let &&&&&Some(&mut x) = &&&&&Some(&mut 0u8) {
|
||||
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, 0u8);
|
||||
}
|
||||
|
||||
if let &&&&&mut Some(&x) = &&&&&mut Some(&0u8) {
|
||||
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, 0u8);
|
||||
}
|
||||
|
||||
if let &mut Some(&mut Some(&mut Some(ref mut x))) = &mut Some(&mut Some(&mut Some(0u8))) {
|
||||
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, &mut 0u8);
|
||||
}
|
||||
|
||||
struct Struct<A, B, C> {
|
||||
a: A,
|
||||
b: B,
|
||||
c: C,
|
||||
}
|
||||
|
||||
let &Struct { ref a, mut b, ref c } = &Struct { a: 0, b: 0, c: 0 };
|
||||
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(a, &0u32);
|
||||
assert_type_eq(b, 0u32);
|
||||
|
||||
let &Struct { a: &a, ref b, ref c } = &Struct { a: &0, b: &0, c: &0 };
|
||||
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(a, 0u32);
|
||||
assert_type_eq(b, &&0u32);
|
||||
assert_type_eq(c, &&0u32);
|
||||
|
||||
if let &Struct { a: &Some(a), b: &Some(&b), c: &Some(ref c) } =
|
||||
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
&(Struct { a: &Some(&0), b: &Some(&0), c: &Some(&0) })
|
||||
{
|
||||
assert_type_eq(a, &0u32);
|
||||
assert_type_eq(b, 0u32);
|
||||
assert_type_eq(c, &&0u32);
|
||||
}
|
||||
|
||||
match &(Some(0), Some(0)) {
|
||||
// The two patterns are the same syntactically, but because they're defined in different
|
||||
// editions they don't mean the same thing.
|
||||
&(Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => {
|
||||
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||
assert_type_eq(x, 0u32);
|
||||
assert_type_eq(y, 0u32);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
@ -0,0 +1,144 @@
|
||||
//@ edition: 2021
|
||||
//@ run-rustfix
|
||||
//@ rustfix-only-machine-applicable
|
||||
//@ aux-build:migration_lint_macros.rs
|
||||
#![feature(mut_ref)]
|
||||
#![allow(incomplete_features, unused)]
|
||||
#![deny(rust_2024_incompatible_pat)]
|
||||
|
||||
extern crate migration_lint_macros;
|
||||
|
||||
struct Foo<T>(T);
|
||||
|
||||
// Tests type equality in a way that avoids coercing `&&T` to `&T`.
|
||||
trait Eq<T> {}
|
||||
impl<T> Eq<T> for T {}
|
||||
fn assert_type_eq<T, U: Eq<T>>(_: T, _: U) {}
|
||||
|
||||
fn main() {
|
||||
let Foo(x) = &Foo(0);
|
||||
assert_type_eq(x, &0u8);
|
||||
|
||||
let Foo(x) = &mut Foo(0);
|
||||
assert_type_eq(x, &mut 0u8);
|
||||
|
||||
let Foo(mut x) = &Foo(0);
|
||||
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, 0u8);
|
||||
|
||||
let Foo(mut x) = &mut Foo(0);
|
||||
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, 0u8);
|
||||
|
||||
let Foo(ref x) = &Foo(0);
|
||||
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, &0u8);
|
||||
|
||||
let Foo(ref x) = &mut Foo(0);
|
||||
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, &0u8);
|
||||
|
||||
let &Foo(x) = &Foo(0);
|
||||
assert_type_eq(x, 0u8);
|
||||
|
||||
let &mut Foo(x) = &mut Foo(0);
|
||||
assert_type_eq(x, 0u8);
|
||||
|
||||
let &Foo(x) = &Foo(&0);
|
||||
assert_type_eq(x, &0u8);
|
||||
|
||||
let &mut Foo(x) = &mut Foo(&0);
|
||||
assert_type_eq(x, &0u8);
|
||||
|
||||
let Foo(&x) = &Foo(&0);
|
||||
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, 0u8);
|
||||
|
||||
let Foo(&mut x) = &Foo(&mut 0);
|
||||
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, 0u8);
|
||||
|
||||
let Foo(&x) = &mut Foo(&0);
|
||||
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, 0u8);
|
||||
|
||||
let Foo(&mut x) = &mut Foo(&mut 0);
|
||||
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, 0u8);
|
||||
|
||||
if let Some(x) = &&&&&Some(&0u8) {
|
||||
assert_type_eq(x, &&0u8);
|
||||
}
|
||||
|
||||
if let Some(&x) = &&&&&Some(&0u8) {
|
||||
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, 0u8);
|
||||
}
|
||||
|
||||
if let Some(&mut x) = &&&&&Some(&mut 0u8) {
|
||||
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, 0u8);
|
||||
}
|
||||
|
||||
if let Some(&x) = &&&&&mut Some(&0u8) {
|
||||
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, 0u8);
|
||||
}
|
||||
|
||||
if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) {
|
||||
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(x, &mut 0u8);
|
||||
}
|
||||
|
||||
struct Struct<A, B, C> {
|
||||
a: A,
|
||||
b: B,
|
||||
c: C,
|
||||
}
|
||||
|
||||
let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 };
|
||||
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(a, &0u32);
|
||||
assert_type_eq(b, 0u32);
|
||||
|
||||
let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 };
|
||||
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(a, 0u32);
|
||||
assert_type_eq(b, &&0u32);
|
||||
assert_type_eq(c, &&0u32);
|
||||
|
||||
if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } =
|
||||
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
&(Struct { a: &Some(&0), b: &Some(&0), c: &Some(&0) })
|
||||
{
|
||||
assert_type_eq(a, &0u32);
|
||||
assert_type_eq(b, 0u32);
|
||||
assert_type_eq(c, &&0u32);
|
||||
}
|
||||
|
||||
match &(Some(0), Some(0)) {
|
||||
// The two patterns are the same syntactically, but because they're defined in different
|
||||
// editions they don't mean the same thing.
|
||||
(Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => {
|
||||
//~^ ERROR: patterns are not allowed to reset the default binding mode
|
||||
assert_type_eq(x, 0u32);
|
||||
assert_type_eq(y, 0u32);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
@ -0,0 +1,188 @@
|
||||
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||
--> $DIR/migration_lint.rs:25:9
|
||||
|
|
||||
LL | let Foo(mut x) = &Foo(0);
|
||||
| -^^^^^^^^^
|
||||
| |
|
||||
| help: desugar the match ergonomics: `&`
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see 123076
|
||||
note: the lint level is defined here
|
||||
--> $DIR/migration_lint.rs:7:9
|
||||
|
|
||||
LL | #![deny(rust_2024_incompatible_pat)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||
--> $DIR/migration_lint.rs:30:9
|
||||
|
|
||||
LL | let Foo(mut x) = &mut Foo(0);
|
||||
| -^^^^^^^^^
|
||||
| |
|
||||
| help: desugar the match ergonomics: `&mut`
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see 123076
|
||||
|
||||
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||
--> $DIR/migration_lint.rs:35:9
|
||||
|
|
||||
LL | let Foo(ref x) = &Foo(0);
|
||||
| -^^^^^^^^^
|
||||
| |
|
||||
| help: desugar the match ergonomics: `&`
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see 123076
|
||||
|
||||
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||
--> $DIR/migration_lint.rs:40:9
|
||||
|
|
||||
LL | let Foo(ref x) = &mut Foo(0);
|
||||
| -^^^^^^^^^
|
||||
| |
|
||||
| help: desugar the match ergonomics: `&mut`
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see 123076
|
||||
|
||||
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||
--> $DIR/migration_lint.rs:57:9
|
||||
|
|
||||
LL | let Foo(&x) = &Foo(&0);
|
||||
| -^^^^^^
|
||||
| |
|
||||
| help: desugar the match ergonomics: `&`
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see 123076
|
||||
|
||||
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||
--> $DIR/migration_lint.rs:62:9
|
||||
|
|
||||
LL | let Foo(&mut x) = &Foo(&mut 0);
|
||||
| -^^^^^^^^^^
|
||||
| |
|
||||
| help: desugar the match ergonomics: `&`
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see 123076
|
||||
|
||||
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||
--> $DIR/migration_lint.rs:67:9
|
||||
|
|
||||
LL | let Foo(&x) = &mut Foo(&0);
|
||||
| -^^^^^^
|
||||
| |
|
||||
| help: desugar the match ergonomics: `&mut`
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see 123076
|
||||
|
||||
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||
--> $DIR/migration_lint.rs:72:9
|
||||
|
|
||||
LL | let Foo(&mut x) = &mut Foo(&mut 0);
|
||||
| -^^^^^^^^^^
|
||||
| |
|
||||
| help: desugar the match ergonomics: `&mut`
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see 123076
|
||||
|
||||
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||
--> $DIR/migration_lint.rs:81:12
|
||||
|
|
||||
LL | if let Some(&x) = &&&&&Some(&0u8) {
|
||||
| -^^^^^^^
|
||||
| |
|
||||
| help: desugar the match ergonomics: `&&&&&`
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see 123076
|
||||
|
||||
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||
--> $DIR/migration_lint.rs:87:12
|
||||
|
|
||||
LL | if let Some(&mut x) = &&&&&Some(&mut 0u8) {
|
||||
| -^^^^^^^^^^^
|
||||
| |
|
||||
| help: desugar the match ergonomics: `&&&&&`
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see 123076
|
||||
|
||||
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||
--> $DIR/migration_lint.rs:93:12
|
||||
|
|
||||
LL | if let Some(&x) = &&&&&mut Some(&0u8) {
|
||||
| -^^^^^^^
|
||||
| |
|
||||
| help: desugar the match ergonomics: `&&&&&mut`
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see 123076
|
||||
|
||||
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||
--> $DIR/migration_lint.rs:99:12
|
||||
|
|
||||
LL | if let Some(&mut Some(Some(x))) = &mut Some(&mut Some(&mut Some(0u8))) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see 123076
|
||||
help: desugar the match ergonomics
|
||||
|
|
||||
LL | if let &mut Some(&mut Some(&mut Some(ref mut x))) = &mut Some(&mut Some(&mut Some(0u8))) {
|
||||
| ++++ ++++ +++++++
|
||||
|
||||
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||
--> $DIR/migration_lint.rs:111:9
|
||||
|
|
||||
LL | let Struct { a, mut b, c } = &Struct { a: 0, b: 0, c: 0 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see 123076
|
||||
help: desugar the match ergonomics
|
||||
|
|
||||
LL | let &Struct { ref a, mut b, ref c } = &Struct { a: 0, b: 0, c: 0 };
|
||||
| + +++ +++
|
||||
|
||||
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||
--> $DIR/migration_lint.rs:117:9
|
||||
|
|
||||
LL | let Struct { a: &a, b, ref c } = &Struct { a: &0, b: &0, c: &0 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see 123076
|
||||
help: desugar the match ergonomics
|
||||
|
|
||||
LL | let &Struct { a: &a, ref b, ref c } = &Struct { a: &0, b: &0, c: &0 };
|
||||
| + +++
|
||||
|
||||
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||
--> $DIR/migration_lint.rs:124:12
|
||||
|
|
||||
LL | if let Struct { a: &Some(a), b: Some(&b), c: Some(c) } =
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see 123076
|
||||
help: desugar the match ergonomics
|
||||
|
|
||||
LL | if let &Struct { a: &Some(a), b: &Some(&b), c: &Some(ref c) } =
|
||||
| + + + +++
|
||||
|
||||
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||
--> $DIR/migration_lint.rs:137:9
|
||||
|
|
||||
LL | (Some(mut x), migration_lint_macros::mixed_edition_pat!(y)) => {
|
||||
| -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| help: desugar the match ergonomics: `&`
|
||||
|
||||
error: aborting due to 16 previous errors
|
||||
|
@ -0,0 +1,46 @@
|
||||
//@ check-fail
|
||||
//@ edition: 2024
|
||||
//@ compile-flags: -Zunstable-options
|
||||
#![deny(rust_2024_incompatible_pat)]
|
||||
|
||||
fn main() {}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
struct T;
|
||||
|
||||
struct Foo {
|
||||
f: &'static (u8,),
|
||||
}
|
||||
|
||||
macro_rules! test_pat_on_type {
|
||||
($($tt:tt)*) => {
|
||||
const _: () = {
|
||||
// Define a new function to ensure all cases are tested independently.
|
||||
fn foo($($tt)*) {}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
test_pat_on_type![(&x,): &(T,)]; //~ ERROR mismatched types
|
||||
test_pat_on_type![(&x,): &(&T,)]; //~ ERROR patterns are not allowed to reset the default binding mode
|
||||
test_pat_on_type![(&x,): &(&mut T,)]; //~ ERROR mismatched types
|
||||
test_pat_on_type![(&mut x,): &(&T,)]; //~ ERROR mismatched types
|
||||
test_pat_on_type![(&mut x,): &(&mut T,)]; //~ ERROR patterns are not allowed to reset the default binding mode
|
||||
test_pat_on_type![(&x,): &&mut &(T,)]; //~ ERROR mismatched types
|
||||
test_pat_on_type![Foo { f: (&x,) }: Foo]; //~ ERROR mismatched types
|
||||
test_pat_on_type![Foo { f: (&x,) }: &mut Foo]; //~ ERROR mismatched types
|
||||
test_pat_on_type![Foo { f: &(x,) }: &Foo]; //~ ERROR patterns are not allowed to reset the default binding mode
|
||||
test_pat_on_type![(mut x,): &(T,)]; //~ ERROR patterns are not allowed to reset the default binding mode
|
||||
test_pat_on_type![(ref x,): &(T,)]; //~ ERROR patterns are not allowed to reset the default binding mode
|
||||
test_pat_on_type![(ref mut x,): &mut (T,)]; //~ ERROR patterns are not allowed to reset the default binding mode
|
||||
|
||||
fn get<X>() -> X {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
// Make sure this works even when the underlying type is inferred. This test passes on rust stable.
|
||||
fn infer<X: Copy>() -> X {
|
||||
match &get() {
|
||||
(&x,) => x, //~ ERROR patterns are not allowed to reset the default binding mode
|
||||
}
|
||||
}
|
@ -0,0 +1,160 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/min_match_ergonomics_fail.rs:24:20
|
||||
|
|
||||
LL | test_pat_on_type![(&x,): &(T,)];
|
||||
| ^^ ----- expected due to this
|
||||
| |
|
||||
| expected `T`, found `&_`
|
||||
|
|
||||
= note: expected struct `T`
|
||||
found reference `&_`
|
||||
help: consider removing `&` from the pattern
|
||||
|
|
||||
LL - test_pat_on_type![(&x,): &(T,)];
|
||||
LL + test_pat_on_type![(x,): &(T,)];
|
||||
|
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/min_match_ergonomics_fail.rs:26:20
|
||||
|
|
||||
LL | test_pat_on_type![(&x,): &(&mut T,)];
|
||||
| ^^ ---------- expected due to this
|
||||
| |
|
||||
| types differ in mutability
|
||||
|
|
||||
= note: expected mutable reference `&mut T`
|
||||
found reference `&_`
|
||||
help: consider removing `&` from the pattern
|
||||
|
|
||||
LL - test_pat_on_type![(&x,): &(&mut T,)];
|
||||
LL + test_pat_on_type![(x,): &(&mut T,)];
|
||||
|
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/min_match_ergonomics_fail.rs:27:20
|
||||
|
|
||||
LL | test_pat_on_type![(&mut x,): &(&T,)];
|
||||
| ^^^^^^ ------ expected due to this
|
||||
| |
|
||||
| types differ in mutability
|
||||
|
|
||||
= note: expected reference `&T`
|
||||
found mutable reference `&mut _`
|
||||
note: to declare a mutable binding use: `mut x`
|
||||
--> $DIR/min_match_ergonomics_fail.rs:27:20
|
||||
|
|
||||
LL | test_pat_on_type![(&mut x,): &(&T,)];
|
||||
| ^^^^^^
|
||||
help: consider removing `&mut` from the pattern
|
||||
|
|
||||
LL - test_pat_on_type![(&mut x,): &(&T,)];
|
||||
LL + test_pat_on_type![(x,): &(&T,)];
|
||||
|
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/min_match_ergonomics_fail.rs:29:20
|
||||
|
|
||||
LL | test_pat_on_type![(&x,): &&mut &(T,)];
|
||||
| ^^ ----------- expected due to this
|
||||
| |
|
||||
| expected `T`, found `&_`
|
||||
|
|
||||
= note: expected struct `T`
|
||||
found reference `&_`
|
||||
help: consider removing `&` from the pattern
|
||||
|
|
||||
LL - test_pat_on_type![(&x,): &&mut &(T,)];
|
||||
LL + test_pat_on_type![(x,): &&mut &(T,)];
|
||||
|
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/min_match_ergonomics_fail.rs:30:29
|
||||
|
|
||||
LL | test_pat_on_type![Foo { f: (&x,) }: Foo];
|
||||
| ^^ --- expected due to this
|
||||
| |
|
||||
| expected `u8`, found `&_`
|
||||
|
|
||||
= note: expected type `u8`
|
||||
found reference `&_`
|
||||
help: consider removing `&` from the pattern
|
||||
|
|
||||
LL - test_pat_on_type![Foo { f: (&x,) }: Foo];
|
||||
LL + test_pat_on_type![Foo { f: (x,) }: Foo];
|
||||
|
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/min_match_ergonomics_fail.rs:31:29
|
||||
|
|
||||
LL | test_pat_on_type![Foo { f: (&x,) }: &mut Foo];
|
||||
| ^^ -------- expected due to this
|
||||
| |
|
||||
| expected `u8`, found `&_`
|
||||
|
|
||||
= note: expected type `u8`
|
||||
found reference `&_`
|
||||
help: consider removing `&` from the pattern
|
||||
|
|
||||
LL - test_pat_on_type![Foo { f: (&x,) }: &mut Foo];
|
||||
LL + test_pat_on_type![Foo { f: (x,) }: &mut Foo];
|
||||
|
|
||||
|
||||
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||
--> $DIR/min_match_ergonomics_fail.rs:25:19
|
||||
|
|
||||
LL | test_pat_on_type![(&x,): &(&T,)];
|
||||
| -^^^^
|
||||
| |
|
||||
| help: desugar the match ergonomics: `&`
|
||||
|
||||
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||
--> $DIR/min_match_ergonomics_fail.rs:28:19
|
||||
|
|
||||
LL | test_pat_on_type![(&mut x,): &(&mut T,)];
|
||||
| -^^^^^^^^
|
||||
| |
|
||||
| help: desugar the match ergonomics: `&`
|
||||
|
||||
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||
--> $DIR/min_match_ergonomics_fail.rs:32:19
|
||||
|
|
||||
LL | test_pat_on_type![Foo { f: &(x,) }: &Foo];
|
||||
| -^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| help: desugar the match ergonomics: `&`
|
||||
|
||||
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||
--> $DIR/min_match_ergonomics_fail.rs:33:19
|
||||
|
|
||||
LL | test_pat_on_type![(mut x,): &(T,)];
|
||||
| -^^^^^^^
|
||||
| |
|
||||
| help: desugar the match ergonomics: `&`
|
||||
|
||||
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||
--> $DIR/min_match_ergonomics_fail.rs:34:19
|
||||
|
|
||||
LL | test_pat_on_type![(ref x,): &(T,)];
|
||||
| -^^^^^^^
|
||||
| |
|
||||
| help: desugar the match ergonomics: `&`
|
||||
|
||||
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||
--> $DIR/min_match_ergonomics_fail.rs:35:19
|
||||
|
|
||||
LL | test_pat_on_type![(ref mut x,): &mut (T,)];
|
||||
| -^^^^^^^^^^^
|
||||
| |
|
||||
| help: desugar the match ergonomics: `&mut`
|
||||
|
||||
error: patterns are not allowed to reset the default binding mode in edition 2024
|
||||
--> $DIR/min_match_ergonomics_fail.rs:44:9
|
||||
|
|
||||
LL | (&x,) => x,
|
||||
| -^^^^
|
||||
| |
|
||||
| help: desugar the match ergonomics: `&`
|
||||
|
||||
error: aborting due to 13 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
@ -0,0 +1,17 @@
|
||||
//@ check-pass
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
fn main() {}
|
||||
|
||||
// Tests type equality in a way that avoids coercing `&&T` to `&T`.
|
||||
trait Eq<T> {}
|
||||
impl<T> Eq<T> for T {}
|
||||
fn assert_type_eq<T, U: Eq<T>>(_: T, _: U) {}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
struct T;
|
||||
|
||||
fn test() {
|
||||
let (x,) = &(&T,);
|
||||
assert_type_eq(x, &&T);
|
||||
}
|
@ -13,9 +13,14 @@ fn main() {
|
||||
}
|
||||
|
||||
fn weird0() -> impl Sized + !Sized {}
|
||||
//~^ ERROR type mismatch resolving `impl !Sized + Sized == ()`
|
||||
//~^ ERROR the trait bound `(): !Sized` is not satisfied
|
||||
//~| ERROR the trait bound `(): !Sized` is not satisfied
|
||||
//~| ERROR the trait bound `(): !Sized` is not satisfied
|
||||
fn weird1() -> impl !Sized + Sized {}
|
||||
//~^ ERROR type mismatch resolving `impl !Sized + Sized == ()`
|
||||
//~^ ERROR the trait bound `(): !Sized` is not satisfied
|
||||
//~| ERROR the trait bound `(): !Sized` is not satisfied
|
||||
//~| ERROR the trait bound `(): !Sized` is not satisfied
|
||||
fn weird2() -> impl !Sized {}
|
||||
//~^ ERROR type mismatch resolving `impl !Sized == ()`
|
||||
//~| ERROR the size for values of type `impl !Sized` cannot be known at compilation time
|
||||
//~^ ERROR the trait bound `(): !Sized` is not satisfied
|
||||
//~| ERROR the trait bound `(): !Sized` is not satisfied
|
||||
//~| ERROR the trait bound `(): !Sized` is not satisfied
|
||||
|
@ -1,29 +1,56 @@
|
||||
error[E0271]: type mismatch resolving `impl !Sized + Sized == ()`
|
||||
error[E0277]: the trait bound `(): !Sized` is not satisfied
|
||||
--> $DIR/opaque-type-unsatisfied-bound.rs:15:16
|
||||
|
|
||||
LL | fn weird0() -> impl Sized + !Sized {}
|
||||
| ^^^^^^^^^^^^^^^^^^^ types differ
|
||||
| ^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
|
||||
|
||||
error[E0271]: type mismatch resolving `impl !Sized + Sized == ()`
|
||||
--> $DIR/opaque-type-unsatisfied-bound.rs:17:16
|
||||
error[E0277]: the trait bound `(): !Sized` is not satisfied
|
||||
--> $DIR/opaque-type-unsatisfied-bound.rs:15:36
|
||||
|
|
||||
LL | fn weird0() -> impl Sized + !Sized {}
|
||||
| ^^ the trait bound `(): !Sized` is not satisfied
|
||||
|
||||
error[E0277]: the trait bound `(): !Sized` is not satisfied
|
||||
--> $DIR/opaque-type-unsatisfied-bound.rs:15:1
|
||||
|
|
||||
LL | fn weird0() -> impl Sized + !Sized {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
|
||||
|
||||
error[E0277]: the trait bound `(): !Sized` is not satisfied
|
||||
--> $DIR/opaque-type-unsatisfied-bound.rs:19:16
|
||||
|
|
||||
LL | fn weird1() -> impl !Sized + Sized {}
|
||||
| ^^^^^^^^^^^^^^^^^^^ types differ
|
||||
| ^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
|
||||
|
||||
error[E0271]: type mismatch resolving `impl !Sized == ()`
|
||||
--> $DIR/opaque-type-unsatisfied-bound.rs:19:16
|
||||
error[E0277]: the trait bound `(): !Sized` is not satisfied
|
||||
--> $DIR/opaque-type-unsatisfied-bound.rs:19:36
|
||||
|
|
||||
LL | fn weird1() -> impl !Sized + Sized {}
|
||||
| ^^ the trait bound `(): !Sized` is not satisfied
|
||||
|
||||
error[E0277]: the trait bound `(): !Sized` is not satisfied
|
||||
--> $DIR/opaque-type-unsatisfied-bound.rs:19:1
|
||||
|
|
||||
LL | fn weird1() -> impl !Sized + Sized {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
|
||||
|
||||
error[E0277]: the trait bound `(): !Sized` is not satisfied
|
||||
--> $DIR/opaque-type-unsatisfied-bound.rs:23:16
|
||||
|
|
||||
LL | fn weird2() -> impl !Sized {}
|
||||
| ^^^^^^^^^^^ types differ
|
||||
| ^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
|
||||
|
||||
error[E0277]: the size for values of type `impl !Sized` cannot be known at compilation time
|
||||
--> $DIR/opaque-type-unsatisfied-bound.rs:19:16
|
||||
error[E0277]: the trait bound `(): !Sized` is not satisfied
|
||||
--> $DIR/opaque-type-unsatisfied-bound.rs:23:28
|
||||
|
|
||||
LL | fn weird2() -> impl !Sized {}
|
||||
| ^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
| ^^ the trait bound `(): !Sized` is not satisfied
|
||||
|
||||
error[E0277]: the trait bound `(): !Sized` is not satisfied
|
||||
--> $DIR/opaque-type-unsatisfied-bound.rs:23:1
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `impl !Sized`
|
||||
= note: the return type of a function must have a statically known size
|
||||
LL | fn weird2() -> impl !Sized {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Sized` is not satisfied
|
||||
|
||||
error[E0277]: the trait bound `impl !Trait: Trait` is not satisfied
|
||||
--> $DIR/opaque-type-unsatisfied-bound.rs:12:13
|
||||
@ -39,7 +66,6 @@ note: required by a bound in `consume`
|
||||
LL | fn consume(_: impl Trait) {}
|
||||
| ^^^^^ required by this bound in `consume`
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
error: aborting due to 10 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0271, E0277.
|
||||
For more information about an error, try `rustc --explain E0271`.
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
@ -3,6 +3,8 @@
|
||||
#![feature(negative_bounds, unboxed_closures)]
|
||||
|
||||
fn produce() -> impl !Fn<(u32,)> {}
|
||||
//~^ ERROR type mismatch resolving `impl !Fn<(u32,)> == ()`
|
||||
//~^ ERROR the trait bound `(): !Fn(u32)` is not satisfied
|
||||
//~| ERROR the trait bound `(): !Fn(u32)` is not satisfied
|
||||
//~| ERROR the trait bound `(): !Fn(u32)` is not satisfied
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,9 +1,21 @@
|
||||
error[E0271]: type mismatch resolving `impl !Fn<(u32,)> == ()`
|
||||
error[E0277]: the trait bound `(): !Fn(u32)` is not satisfied
|
||||
--> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:17
|
||||
|
|
||||
LL | fn produce() -> impl !Fn<(u32,)> {}
|
||||
| ^^^^^^^^^^^^^^^^ types differ
|
||||
| ^^^^^^^^^^^^^^^^ the trait bound `(): !Fn(u32)` is not satisfied
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
error[E0277]: the trait bound `(): !Fn(u32)` is not satisfied
|
||||
--> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:34
|
||||
|
|
||||
LL | fn produce() -> impl !Fn<(u32,)> {}
|
||||
| ^^ the trait bound `(): !Fn(u32)` is not satisfied
|
||||
|
||||
For more information about this error, try `rustc --explain E0271`.
|
||||
error[E0277]: the trait bound `(): !Fn(u32)` is not satisfied
|
||||
--> $DIR/opaque-type-unsatisfied-fn-bound.rs:5:1
|
||||
|
|
||||
LL | fn produce() -> impl !Fn<(u32,)> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait bound `(): !Fn(u32)` is not satisfied
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
@ -17,7 +17,7 @@ trait Overlap<T> {}
|
||||
impl<T> Overlap<T> for T {}
|
||||
|
||||
impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {}
|
||||
//~^ ERROR conflicting implementations of trait `Overlap<fn(_)>` for type `fn(_)`
|
||||
//~| ERROR cannot find type `Missing` in this scope
|
||||
//~^ ERROR cannot find type `Missing` in this scope
|
||||
//~| ERROR the trait bound `for<'a> *const T: ToUnit<'a>` is not satisfied
|
||||
|
||||
fn main() {}
|
||||
|
@ -26,21 +26,19 @@ LL | trait ToUnit<'a> {
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), .. }
|
||||
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), .. }
|
||||
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), .. }
|
||||
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), .. }
|
||||
error[E0119]: conflicting implementations of trait `Overlap<fn(_)>` for type `fn(_)`
|
||||
--> $DIR/issue-118950-root-region.rs:19:1
|
||||
error[E0277]: the trait bound `for<'a> *const T: ToUnit<'a>` is not satisfied
|
||||
--> $DIR/issue-118950-root-region.rs:19:17
|
||||
|
|
||||
LL | impl<T> Overlap<T> for T {}
|
||||
| ------------------------ first implementation here
|
||||
LL |
|
||||
LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `fn(_)`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `*const T`
|
||||
|
|
||||
= note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details
|
||||
help: this trait has no implementations, consider adding one
|
||||
--> $DIR/issue-118950-root-region.rs:8:1
|
||||
|
|
||||
LL | trait ToUnit<'a> {
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 3 previous errors; 1 warning emitted
|
||||
|
||||
Some errors have detailed explanations: E0119, E0277, E0412.
|
||||
For more information about an error, try `rustc --explain E0119`.
|
||||
Some errors have detailed explanations: E0277, E0412.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
||||
|
@ -15,7 +15,7 @@ trait Foo {
|
||||
impl<T: ?Sized> Mirror for T { type Assoc = T; }
|
||||
|
||||
trait MirrorRegion<'a> { type Assoc: ?Sized; }
|
||||
impl<'a, T> MirrorRegion<'a> for T { type Assoc = T; }
|
||||
impl<'a, T: ?Sized> MirrorRegion<'a> for T { type Assoc = T; }
|
||||
|
||||
impl<T> Foo for T {
|
||||
#[cfg(normalize_param_env)]
|
||||
|
@ -1,11 +1,9 @@
|
||||
//@ revisions: current next
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
//@[next] check-pass
|
||||
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||
//@[current] check-fail
|
||||
//@[current] failure-status: 101
|
||||
//@[current] dont-check-compiler-stderr
|
||||
//@[current] known-bug: #103899
|
||||
//@ check-fail
|
||||
//@ failure-status: 101
|
||||
//@ dont-check-compiler-stderr
|
||||
//@ known-bug: #103899
|
||||
|
||||
trait BaseWithAssoc {
|
||||
type Assoc;
|
||||
|
Loading…
Reference in New Issue
Block a user