Auto merge of #131275 - workingjubilee:rollup-4yxqio3, r=workingjubilee
Rollup of 9 pull requests Successful merges: - #129517 (Compute array length from type for unconditional panic lint. ) - #130367 (Check elaborated projections from dyn don't mention unconstrained late bound lifetimes) - #130403 (Stabilize `const_slice_from_raw_parts_mut`) - #130633 (Add support for reborrowing pinned method receivers) - #131105 (update `Literal`'s intro) - #131194 (Fix needless_lifetimes in stable_mir) - #131260 (rustdoc: cleaner errors on disambiguator/namespace mismatches) - #131267 (Stabilize `BufRead::skip_until`) - #131273 (Account for `impl Trait {` when `impl Trait for Type {` was intended) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
d30c3924a4
43 changed files with 559 additions and 94 deletions
|
@ -13,6 +13,7 @@ use rustc_middle::ty::{
|
|||
use rustc_span::{ErrorGuaranteed, Span};
|
||||
use rustc_trait_selection::error_reporting::traits::report_dyn_incompatibility;
|
||||
use rustc_trait_selection::traits::{self, hir_ty_lowering_dyn_compatibility_violations};
|
||||
use rustc_type_ir::elaborate::ClauseWithSupertraitSpan;
|
||||
use smallvec::{SmallVec, smallvec};
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
|
@ -124,16 +125,19 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
.into_iter()
|
||||
.filter(|(trait_ref, _)| !tcx.trait_is_auto(trait_ref.def_id()));
|
||||
|
||||
for (base_trait_ref, span) in regular_traits_refs_spans {
|
||||
for (base_trait_ref, original_span) in regular_traits_refs_spans {
|
||||
let base_pred: ty::Predicate<'tcx> = base_trait_ref.upcast(tcx);
|
||||
for pred in traits::elaborate(tcx, [base_pred]).filter_only_self() {
|
||||
for ClauseWithSupertraitSpan { pred, original_span, supertrait_span } in
|
||||
traits::elaborate(tcx, [ClauseWithSupertraitSpan::new(base_pred, original_span)])
|
||||
.filter_only_self()
|
||||
{
|
||||
debug!("observing object predicate `{pred:?}`");
|
||||
|
||||
let bound_predicate = pred.kind();
|
||||
match bound_predicate.skip_binder() {
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => {
|
||||
let pred = bound_predicate.rebind(pred);
|
||||
associated_types.entry(span).or_default().extend(
|
||||
associated_types.entry(original_span).or_default().extend(
|
||||
tcx.associated_items(pred.def_id())
|
||||
.in_definition_order()
|
||||
.filter(|item| item.kind == ty::AssocKind::Type)
|
||||
|
@ -172,8 +176,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
// the discussion in #56288 for alternatives.
|
||||
if !references_self {
|
||||
// Include projections defined on supertraits.
|
||||
projection_bounds.push((pred, span));
|
||||
projection_bounds.push((pred, original_span));
|
||||
}
|
||||
|
||||
self.check_elaborated_projection_mentions_input_lifetimes(
|
||||
pred,
|
||||
original_span,
|
||||
supertrait_span,
|
||||
);
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
@ -360,6 +370,56 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
|
||||
Ty::new_dynamic(tcx, existential_predicates, region_bound, representation)
|
||||
}
|
||||
|
||||
/// Check that elaborating the principal of a trait ref doesn't lead to projections
|
||||
/// that are unconstrained. This can happen because an otherwise unconstrained
|
||||
/// *type variable* can be substituted with a type that has late-bound regions. See
|
||||
/// `elaborated-predicates-unconstrained-late-bound.rs` for a test.
|
||||
fn check_elaborated_projection_mentions_input_lifetimes(
|
||||
&self,
|
||||
pred: ty::PolyProjectionPredicate<'tcx>,
|
||||
span: Span,
|
||||
supertrait_span: Span,
|
||||
) {
|
||||
let tcx = self.tcx();
|
||||
|
||||
// Find any late-bound regions declared in `ty` that are not
|
||||
// declared in the trait-ref or assoc_item. These are not well-formed.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// for<'a> <T as Iterator>::Item = &'a str // <-- 'a is bad
|
||||
// for<'a> <T as FnMut<(&'a u32,)>>::Output = &'a str // <-- 'a is ok
|
||||
let late_bound_in_projection_term =
|
||||
tcx.collect_constrained_late_bound_regions(pred.map_bound(|pred| pred.projection_term));
|
||||
let late_bound_in_term =
|
||||
tcx.collect_referenced_late_bound_regions(pred.map_bound(|pred| pred.term));
|
||||
debug!(?late_bound_in_projection_term);
|
||||
debug!(?late_bound_in_term);
|
||||
|
||||
// FIXME: point at the type params that don't have appropriate lifetimes:
|
||||
// struct S1<F: for<'a> Fn(&i32, &i32) -> &'a i32>(F);
|
||||
// ---- ---- ^^^^^^^
|
||||
// NOTE(associated_const_equality): This error should be impossible to trigger
|
||||
// with associated const equality constraints.
|
||||
self.validate_late_bound_regions(
|
||||
late_bound_in_projection_term,
|
||||
late_bound_in_term,
|
||||
|br_name| {
|
||||
let item_name = tcx.item_name(pred.projection_def_id());
|
||||
struct_span_code_err!(
|
||||
self.dcx(),
|
||||
span,
|
||||
E0582,
|
||||
"binding for associated type `{}` references {}, \
|
||||
which does not appear in the trait input types",
|
||||
item_name,
|
||||
br_name
|
||||
)
|
||||
.with_span_label(supertrait_span, "due to this supertrait")
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn replace_dummy_self_with_error<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
|
||||
|
|
|
@ -108,17 +108,20 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
let tcx = self.tcx();
|
||||
let parent_id = tcx.hir().get_parent_item(self_ty.hir_id).def_id;
|
||||
if let hir::Node::Item(hir::Item {
|
||||
kind:
|
||||
hir::ItemKind::Impl(hir::Impl {
|
||||
self_ty: impl_self_ty,
|
||||
of_trait: Some(of_trait_ref),
|
||||
generics,
|
||||
..
|
||||
}),
|
||||
kind: hir::ItemKind::Impl(hir::Impl { self_ty: impl_self_ty, of_trait, generics, .. }),
|
||||
..
|
||||
}) = tcx.hir_node_by_def_id(parent_id)
|
||||
&& self_ty.hir_id == impl_self_ty.hir_id
|
||||
{
|
||||
let Some(of_trait_ref) = of_trait else {
|
||||
diag.span_suggestion_verbose(
|
||||
impl_self_ty.span.shrink_to_hi(),
|
||||
"you might have intended to implement this trait for a given type",
|
||||
format!(" for /* Type */"),
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
return;
|
||||
};
|
||||
if !of_trait_ref.trait_def_id().is_some_and(|def_id| def_id.is_local()) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -235,6 +235,23 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
|||
target,
|
||||
});
|
||||
}
|
||||
|
||||
Some(probe::AutorefOrPtrAdjustment::ReborrowPin(mutbl)) => {
|
||||
let region = self.next_region_var(infer::Autoref(self.span));
|
||||
|
||||
target = match target.kind() {
|
||||
ty::Adt(pin, args) if self.tcx.is_lang_item(pin.did(), hir::LangItem::Pin) => {
|
||||
let inner_ty = match args[0].expect_ty().kind() {
|
||||
ty::Ref(_, ty, _) => *ty,
|
||||
_ => bug!("Expected a reference type for argument to Pin"),
|
||||
};
|
||||
Ty::new_pinned_ref(self.tcx, region, inner_ty, mutbl)
|
||||
}
|
||||
_ => bug!("Cannot adjust receiver type for reborrowing pin of {target:?}"),
|
||||
};
|
||||
|
||||
adjustments.push(Adjustment { kind: Adjust::ReborrowPin(region, mutbl), target });
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
|
||||
|
|
|
@ -121,16 +121,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
mutbl.ref_prefix_str()
|
||||
}
|
||||
Some(probe::AutorefOrPtrAdjustment::ToConstPtr) | None => "",
|
||||
Some(probe::AutorefOrPtrAdjustment::ReborrowPin(mutbl)) => match mutbl {
|
||||
hir::Mutability::Mut => "Pin<&mut ",
|
||||
hir::Mutability::Not => "Pin<&",
|
||||
},
|
||||
};
|
||||
if let Ok(self_expr) = self.sess().source_map().span_to_snippet(self_expr.span)
|
||||
{
|
||||
let self_adjusted = if let Some(probe::AutorefOrPtrAdjustment::ToConstPtr) =
|
||||
let mut self_adjusted =
|
||||
if let Some(probe::AutorefOrPtrAdjustment::ToConstPtr) =
|
||||
pick.autoref_or_ptr_adjustment
|
||||
{
|
||||
format!("{derefs}{self_expr} as *const _")
|
||||
} else {
|
||||
format!("{autoref}{derefs}{self_expr}")
|
||||
};
|
||||
|
||||
if let Some(probe::AutorefOrPtrAdjustment::ReborrowPin(_)) =
|
||||
pick.autoref_or_ptr_adjustment
|
||||
{
|
||||
format!("{derefs}{self_expr} as *const _")
|
||||
} else {
|
||||
format!("{autoref}{derefs}{self_expr}")
|
||||
};
|
||||
self_adjusted.push('>');
|
||||
}
|
||||
|
||||
lint.span_suggestion(
|
||||
sp,
|
||||
|
@ -400,6 +411,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
let autoref = match pick.autoref_or_ptr_adjustment {
|
||||
Some(probe::AutorefOrPtrAdjustment::Autoref { mutbl, .. }) => mutbl.ref_prefix_str(),
|
||||
Some(probe::AutorefOrPtrAdjustment::ToConstPtr) | None => "",
|
||||
Some(probe::AutorefOrPtrAdjustment::ReborrowPin(mutbl)) => match mutbl {
|
||||
hir::Mutability::Mut => "Pin<&mut ",
|
||||
hir::Mutability::Not => "Pin<&",
|
||||
},
|
||||
};
|
||||
|
||||
let (expr_text, precise) = if let Some(expr_text) = expr
|
||||
|
@ -412,7 +427,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
("(..)".to_string(), false)
|
||||
};
|
||||
|
||||
let adjusted_text = if let Some(probe::AutorefOrPtrAdjustment::ToConstPtr) =
|
||||
let mut adjusted_text = if let Some(probe::AutorefOrPtrAdjustment::ToConstPtr) =
|
||||
pick.autoref_or_ptr_adjustment
|
||||
{
|
||||
format!("{derefs}{expr_text} as *const _")
|
||||
|
@ -420,6 +435,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
format!("{autoref}{derefs}{expr_text}")
|
||||
};
|
||||
|
||||
if let Some(probe::AutorefOrPtrAdjustment::ReborrowPin(_)) = pick.autoref_or_ptr_adjustment
|
||||
{
|
||||
adjusted_text.push('>');
|
||||
}
|
||||
|
||||
(adjusted_text, precise)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -136,7 +136,7 @@ enum ProbeResult {
|
|||
/// `mut`), or it has type `*mut T` and we convert it to `*const T`.
|
||||
#[derive(Debug, PartialEq, Copy, Clone)]
|
||||
pub(crate) enum AutorefOrPtrAdjustment {
|
||||
/// Receiver has type `T`, add `&` or `&mut` (it `T` is `mut`), and maybe also "unsize" it.
|
||||
/// Receiver has type `T`, add `&` or `&mut` (if `T` is `mut`), and maybe also "unsize" it.
|
||||
/// Unsizing is used to convert a `[T; N]` to `[T]`, which only makes sense when autorefing.
|
||||
Autoref {
|
||||
mutbl: hir::Mutability,
|
||||
|
@ -147,6 +147,9 @@ pub(crate) enum AutorefOrPtrAdjustment {
|
|||
},
|
||||
/// Receiver has type `*mut T`, convert to `*const T`
|
||||
ToConstPtr,
|
||||
|
||||
/// Reborrow a `Pin<&mut T>` or `Pin<&T>`.
|
||||
ReborrowPin(hir::Mutability),
|
||||
}
|
||||
|
||||
impl AutorefOrPtrAdjustment {
|
||||
|
@ -154,6 +157,7 @@ impl AutorefOrPtrAdjustment {
|
|||
match self {
|
||||
AutorefOrPtrAdjustment::Autoref { mutbl: _, unsize } => *unsize,
|
||||
AutorefOrPtrAdjustment::ToConstPtr => false,
|
||||
AutorefOrPtrAdjustment::ReborrowPin(_) => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1103,6 +1107,13 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||
unstable_candidates.as_deref_mut(),
|
||||
)
|
||||
})
|
||||
.or_else(|| {
|
||||
self.pick_reborrow_pin_method(
|
||||
step,
|
||||
self_ty,
|
||||
unstable_candidates.as_deref_mut(),
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
@ -1127,13 +1138,28 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||
r.map(|mut pick| {
|
||||
pick.autoderefs = step.autoderefs;
|
||||
|
||||
// Insert a `&*` or `&mut *` if this is a reference type:
|
||||
if let ty::Ref(_, _, mutbl) = *step.self_ty.value.value.kind() {
|
||||
pick.autoderefs += 1;
|
||||
pick.autoref_or_ptr_adjustment = Some(AutorefOrPtrAdjustment::Autoref {
|
||||
mutbl,
|
||||
unsize: pick.autoref_or_ptr_adjustment.is_some_and(|a| a.get_unsize()),
|
||||
})
|
||||
match *step.self_ty.value.value.kind() {
|
||||
// Insert a `&*` or `&mut *` if this is a reference type:
|
||||
ty::Ref(_, _, mutbl) => {
|
||||
pick.autoderefs += 1;
|
||||
pick.autoref_or_ptr_adjustment = Some(AutorefOrPtrAdjustment::Autoref {
|
||||
mutbl,
|
||||
unsize: pick.autoref_or_ptr_adjustment.is_some_and(|a| a.get_unsize()),
|
||||
})
|
||||
}
|
||||
|
||||
ty::Adt(def, args)
|
||||
if self.tcx.features().pin_ergonomics
|
||||
&& self.tcx.is_lang_item(def.did(), hir::LangItem::Pin) =>
|
||||
{
|
||||
// make sure this is a pinned reference (and not a `Pin<Box>` or something)
|
||||
if let ty::Ref(_, _, mutbl) = args[0].expect_ty().kind() {
|
||||
pick.autoref_or_ptr_adjustment =
|
||||
Some(AutorefOrPtrAdjustment::ReborrowPin(*mutbl));
|
||||
}
|
||||
}
|
||||
|
||||
_ => (),
|
||||
}
|
||||
|
||||
pick
|
||||
|
@ -1164,6 +1190,43 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||
})
|
||||
}
|
||||
|
||||
/// Looks for applicable methods if we reborrow a `Pin<&mut T>` as a `Pin<&T>`.
|
||||
#[instrument(level = "debug", skip(self, step, unstable_candidates))]
|
||||
fn pick_reborrow_pin_method(
|
||||
&self,
|
||||
step: &CandidateStep<'tcx>,
|
||||
self_ty: Ty<'tcx>,
|
||||
unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>,
|
||||
) -> Option<PickResult<'tcx>> {
|
||||
if !self.tcx.features().pin_ergonomics {
|
||||
return None;
|
||||
}
|
||||
|
||||
// make sure self is a Pin<&mut T>
|
||||
let inner_ty = match self_ty.kind() {
|
||||
ty::Adt(def, args) if self.tcx.is_lang_item(def.did(), hir::LangItem::Pin) => {
|
||||
match args[0].expect_ty().kind() {
|
||||
ty::Ref(_, ty, hir::Mutability::Mut) => *ty,
|
||||
_ => {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
let region = self.tcx.lifetimes.re_erased;
|
||||
let autopin_ty = Ty::new_pinned_ref(self.tcx, region, inner_ty, hir::Mutability::Not);
|
||||
self.pick_method(autopin_ty, unstable_candidates).map(|r| {
|
||||
r.map(|mut pick| {
|
||||
pick.autoderefs = step.autoderefs;
|
||||
pick.autoref_or_ptr_adjustment =
|
||||
Some(AutorefOrPtrAdjustment::ReborrowPin(hir::Mutability::Not));
|
||||
pick
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/// If `self_ty` is `*mut T` then this picks `*const T` methods. The reason why we have a
|
||||
/// special case for this is because going from `*mut T` to `*const T` with autoderefs and
|
||||
/// autorefs would require dereferencing the pointer, which is not safe.
|
||||
|
|
|
@ -179,6 +179,10 @@ pub struct Clause<'tcx>(
|
|||
);
|
||||
|
||||
impl<'tcx> rustc_type_ir::inherent::Clause<TyCtxt<'tcx>> for Clause<'tcx> {
|
||||
fn as_predicate(self) -> Predicate<'tcx> {
|
||||
self.as_predicate()
|
||||
}
|
||||
|
||||
fn instantiate_supertrait(self, tcx: TyCtxt<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>) -> Self {
|
||||
self.instantiate_supertrait(tcx, trait_ref)
|
||||
}
|
||||
|
|
|
@ -584,6 +584,16 @@ impl<'tcx> Ty<'tcx> {
|
|||
Ty::new_ref(tcx, r, ty, hir::Mutability::Not)
|
||||
}
|
||||
|
||||
pub fn new_pinned_ref(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
r: Region<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
mutbl: ty::Mutability,
|
||||
) -> Ty<'tcx> {
|
||||
let pin = tcx.adt_def(tcx.require_lang_item(LangItem::Pin, None));
|
||||
Ty::new_adt(tcx, pin, tcx.mk_args(&[Ty::new_ref(tcx, r, ty, mutbl).into()]))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn new_ptr(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, mutbl: ty::Mutability) -> Ty<'tcx> {
|
||||
Ty::new(tcx, ty::RawPtr(ty, mutbl))
|
||||
|
|
|
@ -600,13 +600,15 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
|||
}
|
||||
|
||||
Len(place) => {
|
||||
let len = match self.get_const(place)? {
|
||||
Value::Immediate(src) => src.len(&self.ecx).discard_err()?,
|
||||
Value::Aggregate { fields, .. } => fields.len() as u64,
|
||||
Value::Uninit => match place.ty(self.local_decls(), self.tcx).ty.kind() {
|
||||
ty::Array(_, n) => n.try_eval_target_usize(self.tcx, self.param_env)?,
|
||||
_ => return None,
|
||||
},
|
||||
let len = if let ty::Array(_, n) = place.ty(self.local_decls(), self.tcx).ty.kind()
|
||||
{
|
||||
n.try_eval_target_usize(self.tcx, self.param_env)?
|
||||
} else {
|
||||
match self.get_const(place)? {
|
||||
Value::Immediate(src) => src.len(&self.ecx).discard_err()?,
|
||||
Value::Aggregate { fields, .. } => fields.len() as u64,
|
||||
Value::Uninit => return None,
|
||||
}
|
||||
};
|
||||
ImmTy::from_scalar(Scalar::from_target_usize(len, self), layout).into()
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use core::ops::ControlFlow;
|
||||
use std::borrow::Cow;
|
||||
|
||||
use rustc_ast::TraitObjectSyntax;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::unord::UnordSet;
|
||||
use rustc_errors::codes::*;
|
||||
|
@ -573,7 +574,26 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
|
||||
ty::PredicateKind::DynCompatible(trait_def_id) => {
|
||||
let violations = self.tcx.dyn_compatibility_violations(trait_def_id);
|
||||
report_dyn_incompatibility(self.tcx, span, None, trait_def_id, violations)
|
||||
let mut err = report_dyn_incompatibility(
|
||||
self.tcx,
|
||||
span,
|
||||
None,
|
||||
trait_def_id,
|
||||
violations,
|
||||
);
|
||||
if let hir::Node::Item(item) =
|
||||
self.tcx.hir_node_by_def_id(obligation.cause.body_id)
|
||||
&& let hir::ItemKind::Impl(impl_) = item.kind
|
||||
&& let None = impl_.of_trait
|
||||
&& let hir::TyKind::TraitObject(_, _, syntax) = impl_.self_ty.kind
|
||||
&& let TraitObjectSyntax::None = syntax
|
||||
&& impl_.self_ty.span.edition().at_least_rust_2021()
|
||||
{
|
||||
// Silence the dyn-compatibility error in favor of the missing dyn on
|
||||
// self type error. #131051.
|
||||
err.downgrade_to_delayed_bug();
|
||||
}
|
||||
err
|
||||
}
|
||||
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(ty)) => {
|
||||
|
|
|
@ -44,6 +44,46 @@ pub trait Elaboratable<I: Interner> {
|
|||
) -> Self;
|
||||
}
|
||||
|
||||
pub struct ClauseWithSupertraitSpan<I: Interner> {
|
||||
pub pred: I::Predicate,
|
||||
// Span of the original elaborated predicate.
|
||||
pub original_span: I::Span,
|
||||
// Span of the supertrait predicatae that lead to this clause.
|
||||
pub supertrait_span: I::Span,
|
||||
}
|
||||
impl<I: Interner> ClauseWithSupertraitSpan<I> {
|
||||
pub fn new(pred: I::Predicate, span: I::Span) -> Self {
|
||||
ClauseWithSupertraitSpan { pred, original_span: span, supertrait_span: span }
|
||||
}
|
||||
}
|
||||
impl<I: Interner> Elaboratable<I> for ClauseWithSupertraitSpan<I> {
|
||||
fn predicate(&self) -> <I as Interner>::Predicate {
|
||||
self.pred
|
||||
}
|
||||
|
||||
fn child(&self, clause: <I as Interner>::Clause) -> Self {
|
||||
ClauseWithSupertraitSpan {
|
||||
pred: clause.as_predicate(),
|
||||
original_span: self.original_span,
|
||||
supertrait_span: self.supertrait_span,
|
||||
}
|
||||
}
|
||||
|
||||
fn child_with_derived_cause(
|
||||
&self,
|
||||
clause: <I as Interner>::Clause,
|
||||
supertrait_span: <I as Interner>::Span,
|
||||
_parent_trait_pred: crate::Binder<I, crate::TraitPredicate<I>>,
|
||||
_index: usize,
|
||||
) -> Self {
|
||||
ClauseWithSupertraitSpan {
|
||||
pred: clause.as_predicate(),
|
||||
original_span: self.original_span,
|
||||
supertrait_span: supertrait_span,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn elaborate<I: Interner, O: Elaboratable<I>>(
|
||||
cx: I,
|
||||
obligations: impl IntoIterator<Item = O>,
|
||||
|
|
|
@ -460,6 +460,8 @@ pub trait Clause<I: Interner<Clause = Self>>:
|
|||
+ IntoKind<Kind = ty::Binder<I, ty::ClauseKind<I>>>
|
||||
+ Elaboratable<I>
|
||||
{
|
||||
fn as_predicate(self) -> I::Predicate;
|
||||
|
||||
fn as_trait_clause(self) -> Option<ty::Binder<I, ty::TraitPredicate<I>>> {
|
||||
self.kind()
|
||||
.map_bound(|clause| if let ty::ClauseKind::Trait(t) = clause { Some(t) } else { None })
|
||||
|
|
|
@ -76,9 +76,9 @@ pub trait MirVisitor {
|
|||
self.super_place(place, ptx, location)
|
||||
}
|
||||
|
||||
fn visit_projection_elem<'a>(
|
||||
fn visit_projection_elem(
|
||||
&mut self,
|
||||
place_ref: PlaceRef<'a>,
|
||||
place_ref: PlaceRef<'_>,
|
||||
elem: &ProjectionElem,
|
||||
ptx: PlaceContext,
|
||||
location: Location,
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#![feature(const_cow_is_borrowed)]
|
||||
#![feature(const_heap)]
|
||||
#![cfg_attr(bootstrap, feature(const_mut_refs))]
|
||||
#![feature(const_slice_from_raw_parts_mut)]
|
||||
#![feature(const_ptr_write)]
|
||||
#![feature(const_try)]
|
||||
#![feature(core_intrinsics)]
|
||||
|
|
|
@ -145,7 +145,6 @@
|
|||
#![feature(const_replace)]
|
||||
#![feature(const_size_of_val)]
|
||||
#![feature(const_size_of_val_raw)]
|
||||
#![feature(const_slice_from_raw_parts_mut)]
|
||||
#![feature(const_slice_from_ref)]
|
||||
#![feature(const_slice_split_at_mut)]
|
||||
#![feature(const_strict_overflow_ops)]
|
||||
|
|
|
@ -992,7 +992,7 @@ pub const fn slice_from_raw_parts<T>(data: *const T, len: usize) -> *const [T] {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "slice_from_raw_parts", since = "1.42.0")]
|
||||
#[rustc_const_unstable(feature = "const_slice_from_raw_parts_mut", issue = "67456")]
|
||||
#[rustc_const_stable(feature = "const_slice_from_raw_parts_mut", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[rustc_diagnostic_item = "ptr_slice_from_raw_parts_mut"]
|
||||
pub const fn slice_from_raw_parts_mut<T>(data: *mut T, len: usize) -> *mut [T] {
|
||||
from_raw_parts_mut(data, len)
|
||||
|
|
|
@ -1434,7 +1434,10 @@ impl<T> NonNull<[T]> {
|
|||
/// (Note that this example artificially demonstrates a use of this method,
|
||||
/// but `let slice = NonNull::from(&x[..]);` would be a better way to write code like this.)
|
||||
#[stable(feature = "nonnull_slice_from_raw_parts", since = "1.70.0")]
|
||||
#[rustc_const_unstable(feature = "const_slice_from_raw_parts_mut", issue = "67456")]
|
||||
#[rustc_const_stable(
|
||||
feature = "const_slice_from_raw_parts_mut",
|
||||
since = "CURRENT_RUSTC_VERSION"
|
||||
)]
|
||||
#[must_use]
|
||||
#[inline]
|
||||
pub const fn slice_from_raw_parts(data: NonNull<T>, len: usize) -> Self {
|
||||
|
|
|
@ -171,7 +171,8 @@ pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T]
|
|||
/// [`NonNull::dangling()`]: ptr::NonNull::dangling
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_slice_from_raw_parts_mut", issue = "67456")]
|
||||
#[rustc_const_stable(feature = "const_slice_from_raw_parts_mut", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))]
|
||||
#[must_use]
|
||||
#[rustc_diagnostic_item = "slice_from_raw_parts_mut"]
|
||||
pub const unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] {
|
||||
|
|
|
@ -1166,7 +1166,7 @@ impl fmt::Debug for Ident {
|
|||
}
|
||||
}
|
||||
|
||||
/// A literal string (`"hello"`), byte string (`b"hello"`),
|
||||
/// A literal string (`"hello"`), byte string (`b"hello"`), C string (`c"hello"`),
|
||||
/// character (`'a'`), byte character (`b'a'`), an integer or floating point number
|
||||
/// with or without a suffix (`1`, `1u8`, `2.3`, `2.3f32`).
|
||||
/// Boolean literals like `true` and `false` do not belong here, they are `Ident`s.
|
||||
|
|
|
@ -2382,8 +2382,6 @@ pub trait BufRead: Read {
|
|||
/// about Ferris from a binary string, skipping the fun fact:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(bufread_skip_until)]
|
||||
///
|
||||
/// use std::io::{self, BufRead};
|
||||
///
|
||||
/// let mut cursor = io::Cursor::new(b"Ferris\0Likes long walks on the beach\0Crustacean\0");
|
||||
|
@ -2407,7 +2405,7 @@ pub trait BufRead: Read {
|
|||
/// assert_eq!(num_bytes, 11);
|
||||
/// assert_eq!(animal, b"Crustacean\0");
|
||||
/// ```
|
||||
#[unstable(feature = "bufread_skip_until", issue = "111735")]
|
||||
#[stable(feature = "bufread_skip_until", since = "CURRENT_RUSTC_VERSION")]
|
||||
fn skip_until(&mut self, byte: u8) -> Result<usize> {
|
||||
skip_until(self, byte)
|
||||
}
|
||||
|
|
|
@ -1996,11 +1996,22 @@ fn resolution_failure(
|
|||
&diag_info,
|
||||
);
|
||||
|
||||
format!(
|
||||
"this link resolves to {}, which is not in the {} namespace",
|
||||
item(res),
|
||||
expected_ns.descr()
|
||||
)
|
||||
if let Some(disambiguator) = disambiguator
|
||||
&& !matches!(disambiguator, Disambiguator::Namespace(..))
|
||||
{
|
||||
format!(
|
||||
"this link resolves to {}, which is not {} {}",
|
||||
item(res),
|
||||
disambiguator.article(),
|
||||
disambiguator.descr()
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
"this link resolves to {}, which is not in the {} namespace",
|
||||
item(res),
|
||||
expected_ns.descr()
|
||||
)
|
||||
}
|
||||
}
|
||||
};
|
||||
if let Some(span) = sp {
|
||||
|
|
|
@ -86,6 +86,7 @@ mod issue9612 {
|
|||
util();
|
||||
}
|
||||
|
||||
#[allow(unconditional_panic)]
|
||||
fn util() {
|
||||
let _a: u8 = 4.try_into().unwrap();
|
||||
let _a: u8 = 5.try_into().expect("");
|
||||
|
|
|
@ -86,6 +86,7 @@ mod issue9612 {
|
|||
util();
|
||||
}
|
||||
|
||||
#[allow(unconditional_panic)]
|
||||
fn util() {
|
||||
let _a: u8 = 4.try_into().unwrap();
|
||||
let _a: u8 = 5.try_into().expect("");
|
||||
|
|
|
@ -274,7 +274,7 @@ LL | let _ = &boxed_slice[1];
|
|||
| ~~~~~~~~~~~~~~~
|
||||
|
||||
error: called `.get().unwrap()` on a slice
|
||||
--> tests/ui-toml/unwrap_used/unwrap_used.rs:93:17
|
||||
--> tests/ui-toml/unwrap_used/unwrap_used.rs:94:17
|
||||
|
|
||||
LL | let _ = Box::new([0]).get(1).unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
@ -70,6 +70,7 @@ fn main() {
|
|||
mod issue9909 {
|
||||
#![allow(clippy::identity_op, clippy::unwrap_used, dead_code)]
|
||||
|
||||
#[allow(unconditional_panic)]
|
||||
fn reduced() {
|
||||
let f = &[1, 2, 3];
|
||||
|
||||
|
|
|
@ -70,6 +70,7 @@ fn main() {
|
|||
mod issue9909 {
|
||||
#![allow(clippy::identity_op, clippy::unwrap_used, dead_code)]
|
||||
|
||||
#[allow(unconditional_panic)]
|
||||
fn reduced() {
|
||||
let f = &[1, 2, 3];
|
||||
|
||||
|
|
|
@ -266,7 +266,7 @@ LL | let _ = some_vec.get_mut(0..1).unwrap().to_vec();
|
|||
= help: consider using `expect()` to provide a better panic message
|
||||
|
||||
error: called `.get().unwrap()` on a slice
|
||||
--> tests/ui/get_unwrap.rs:77:24
|
||||
--> tests/ui/get_unwrap.rs:78:24
|
||||
|
|
||||
LL | let _x: &i32 = f.get(1 + 2).unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -277,7 +277,7 @@ LL | let _x: &i32 = &f[1 + 2];
|
|||
| ~~~~~~~~~
|
||||
|
||||
error: called `.get().unwrap()` on a slice
|
||||
--> tests/ui/get_unwrap.rs:80:18
|
||||
--> tests/ui/get_unwrap.rs:81:18
|
||||
|
|
||||
LL | let _x = f.get(1 + 2).unwrap().to_string();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -288,7 +288,7 @@ LL | let _x = f[1 + 2].to_string();
|
|||
| ~~~~~~~~
|
||||
|
||||
error: called `.get().unwrap()` on a slice
|
||||
--> tests/ui/get_unwrap.rs:83:18
|
||||
--> tests/ui/get_unwrap.rs:84:18
|
||||
|
|
||||
LL | let _x = f.get(1 + 2).unwrap().abs();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -299,7 +299,7 @@ LL | let _x = f[1 + 2].abs();
|
|||
| ~~~~~~~~
|
||||
|
||||
error: called `.get_mut().unwrap()` on a slice
|
||||
--> tests/ui/get_unwrap.rs:100:33
|
||||
--> tests/ui/get_unwrap.rs:101:33
|
||||
|
|
||||
LL | let b = rest.get_mut(linidx(j, k) - linidx(i, k) - 1).unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
@ -74,7 +74,7 @@ error: unresolved link to `m`
|
|||
--> $DIR/disambiguator-mismatch.rs:52:14
|
||||
|
|
||||
LL | /// Link to [m()]
|
||||
| ^^^ this link resolves to the macro `m`, which is not in the value namespace
|
||||
| ^^^ this link resolves to the macro `m`, which is not a function
|
||||
|
|
||||
help: to link to the macro, add an exclamation mark
|
||||
|
|
||||
|
@ -142,7 +142,7 @@ error: unresolved link to `std`
|
|||
--> $DIR/disambiguator-mismatch.rs:83:14
|
||||
|
|
||||
LL | /// Link to [fn@std]
|
||||
| ^^^^^^ this link resolves to the crate `std`, which is not in the value namespace
|
||||
| ^^^^^^ this link resolves to the crate `std`, which is not a function
|
||||
|
|
||||
help: to link to the crate, prefix with `mod@`
|
||||
|
|
||||
|
@ -164,7 +164,7 @@ error: unresolved link to `S::A`
|
|||
--> $DIR/disambiguator-mismatch.rs:93:14
|
||||
|
|
||||
LL | /// Link to [field@S::A]
|
||||
| ^^^^^^^^^^ this link resolves to the variant `A`, which is not in the value namespace
|
||||
| ^^^^^^^^^^ this link resolves to the variant `A`, which is not a field
|
||||
|
|
||||
help: to link to the variant, prefix with `variant@`
|
||||
|
|
||||
|
|
|
@ -98,7 +98,7 @@ pub trait T {
|
|||
/// [m()]
|
||||
//~^ ERROR unresolved link
|
||||
//~| HELP to link to the macro
|
||||
//~| NOTE not in the value namespace
|
||||
//~| NOTE not a function
|
||||
#[macro_export]
|
||||
macro_rules! m {
|
||||
() => {};
|
||||
|
|
|
@ -104,7 +104,7 @@ error: unresolved link to `S`
|
|||
--> $DIR/errors.rs:68:6
|
||||
|
|
||||
LL | /// [S!]
|
||||
| ^^ this link resolves to the struct `S`, which is not in the macro namespace
|
||||
| ^^ this link resolves to the struct `S`, which is not a macro
|
||||
|
|
||||
help: to link to the struct, prefix with `struct@`
|
||||
|
|
||||
|
@ -158,7 +158,7 @@ error: unresolved link to `m`
|
|||
--> $DIR/errors.rs:98:6
|
||||
|
|
||||
LL | /// [m()]
|
||||
| ^^^ this link resolves to the macro `m`, which is not in the value namespace
|
||||
| ^^^ this link resolves to the macro `m`, which is not a function
|
||||
|
|
||||
help: to link to the macro, add an exclamation mark
|
||||
|
|
||||
|
|
|
@ -2,7 +2,7 @@ error: unresolved link to `Clone`
|
|||
--> $DIR/issue-110495-suffix-with-space.rs:3:6
|
||||
|
|
||||
LL | //! [Clone ()].
|
||||
| ^^^^^^^^ this link resolves to the trait `Clone`, which is not in the value namespace
|
||||
| ^^^^^^^^ this link resolves to the trait `Clone`, which is not a function
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/issue-110495-suffix-with-space.rs:2:9
|
||||
|
@ -31,7 +31,7 @@ error: unresolved link to `Clone`
|
|||
--> $DIR/issue-110495-suffix-with-space.rs:5:7
|
||||
|
|
||||
LL | //! [`Clone ()`].
|
||||
| ^^^^^^^^ this link resolves to the trait `Clone`, which is not in the value namespace
|
||||
| ^^^^^^^^ this link resolves to the trait `Clone`, which is not a function
|
||||
|
|
||||
help: to link to the trait, prefix with `trait@`
|
||||
|
|
||||
|
|
|
@ -40,7 +40,7 @@ error: unresolved link to `Clone`
|
|||
--> $DIR/weird-syntax.rs:27:9
|
||||
|
|
||||
LL | /// [ `Clone ()` ]
|
||||
| ^^^^^^^^ this link resolves to the trait `Clone`, which is not in the value namespace
|
||||
| ^^^^^^^^ this link resolves to the trait `Clone`, which is not a function
|
||||
|
|
||||
help: to link to the trait, prefix with `trait@`
|
||||
|
|
||||
|
@ -52,7 +52,7 @@ error: unresolved link to `Clone`
|
|||
--> $DIR/weird-syntax.rs:30:7
|
||||
|
|
||||
LL | /// [`Clone ()` ]
|
||||
| ^^^^^^^^ this link resolves to the trait `Clone`, which is not in the value namespace
|
||||
| ^^^^^^^^ this link resolves to the trait `Clone`, which is not a function
|
||||
|
|
||||
help: to link to the trait, prefix with `trait@`
|
||||
|
|
||||
|
@ -64,7 +64,7 @@ error: unresolved link to `Clone`
|
|||
--> $DIR/weird-syntax.rs:33:9
|
||||
|
|
||||
LL | /// [ `Clone ()`]
|
||||
| ^^^^^^^^ this link resolves to the trait `Clone`, which is not in the value namespace
|
||||
| ^^^^^^^^ this link resolves to the trait `Clone`, which is not a function
|
||||
|
|
||||
help: to link to the trait, prefix with `trait@`
|
||||
|
|
||||
|
@ -76,7 +76,7 @@ error: unresolved link to `Clone`
|
|||
--> $DIR/weird-syntax.rs:36:9
|
||||
|
|
||||
LL | /// [```Clone ()```]
|
||||
| ^^^^^^^^ this link resolves to the trait `Clone`, which is not in the value namespace
|
||||
| ^^^^^^^^ this link resolves to the trait `Clone`, which is not a function
|
||||
|
|
||||
help: to link to the trait, prefix with `trait@`
|
||||
|
|
||||
|
@ -88,7 +88,7 @@ error: unresolved link to `Clone`
|
|||
--> $DIR/weird-syntax.rs:42:13
|
||||
|
|
||||
LL | /// [ ``` Clone () ``` ]
|
||||
| ^^^^^^^^ this link resolves to the trait `Clone`, which is not in the value namespace
|
||||
| ^^^^^^^^ this link resolves to the trait `Clone`, which is not a function
|
||||
|
|
||||
help: to link to the trait, prefix with `trait@`
|
||||
|
|
||||
|
@ -122,7 +122,7 @@ error: unresolved link to `Clone`
|
|||
--> $DIR/weird-syntax.rs:74:9
|
||||
|
|
||||
LL | /// [x][Clone()]
|
||||
| ^^^^^^^ this link resolves to the trait `Clone`, which is not in the value namespace
|
||||
| ^^^^^^^ this link resolves to the trait `Clone`, which is not a function
|
||||
|
|
||||
help: to link to the trait, prefix with `trait@`
|
||||
|
|
||||
|
@ -134,7 +134,7 @@ error: unresolved link to `Clone`
|
|||
--> $DIR/weird-syntax.rs:77:9
|
||||
|
|
||||
LL | /// [x][Clone ()]
|
||||
| ^^^^^^^^^ this link resolves to the trait `Clone`, which is not in the value namespace
|
||||
| ^^^^^^^^^ this link resolves to the trait `Clone`, which is not a function
|
||||
|
|
||||
help: to link to the trait, prefix with `trait@`
|
||||
|
|
||||
|
@ -176,7 +176,7 @@ error: unresolved link to `Clone`
|
|||
--> $DIR/weird-syntax.rs:97:9
|
||||
|
|
||||
LL | /// [w](Clone\(\))
|
||||
| ^^^^^^^^^ this link resolves to the trait `Clone`, which is not in the value namespace
|
||||
| ^^^^^^^^^ this link resolves to the trait `Clone`, which is not a function
|
||||
|
|
||||
help: to link to the trait, prefix with `trait@`
|
||||
|
|
||||
|
@ -188,7 +188,7 @@ error: unresolved link to `Clone`
|
|||
--> $DIR/weird-syntax.rs:103:9
|
||||
|
|
||||
LL | /// [w](Clone())
|
||||
| ^^^^^^^ this link resolves to the trait `Clone`, which is not in the value namespace
|
||||
| ^^^^^^^ this link resolves to the trait `Clone`, which is not a function
|
||||
|
|
||||
help: to link to the trait, prefix with `trait@`
|
||||
|
|
||||
|
@ -256,7 +256,7 @@ error: unresolved link to `Clone`
|
|||
--> $DIR/weird-syntax.rs:132:9
|
||||
|
|
||||
LL | /// The [cln][] link here will produce a plain text suggestion
|
||||
| ^^^^^ this link resolves to the trait `Clone`, which is not in the value namespace
|
||||
| ^^^^^ this link resolves to the trait `Clone`, which is not a function
|
||||
|
|
||||
= help: to link to the trait, prefix with `trait@`: trait@Clone
|
||||
|
||||
|
|
|
@ -1,24 +1,33 @@
|
|||
//@ check-pass
|
||||
//@ignore-test
|
||||
|
||||
// Currently ignored due to self reborrowing not being implemented for Pin
|
||||
|
||||
#![feature(pin_ergonomics)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
use std::pin::Pin;
|
||||
|
||||
struct Foo;
|
||||
pub struct Foo;
|
||||
|
||||
impl Foo {
|
||||
fn foo(self: Pin<&mut Self>) {
|
||||
}
|
||||
|
||||
fn baz(self: Pin<&Self>) {
|
||||
}
|
||||
}
|
||||
|
||||
fn bar(x: Pin<&mut Foo>) {
|
||||
pub fn bar(x: Pin<&mut Foo>) {
|
||||
x.foo();
|
||||
x.foo(); // for this to work we need to automatically reborrow,
|
||||
// as if the user had written `x.as_mut().foo()`.
|
||||
|
||||
Foo::baz(x);
|
||||
|
||||
x.baz();
|
||||
}
|
||||
|
||||
pub fn baaz(x: Pin<&Foo>) {
|
||||
x.baz();
|
||||
x.baz();
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -4,6 +4,11 @@ use std::pin::Pin;
|
|||
|
||||
struct Foo;
|
||||
|
||||
impl Foo {
|
||||
fn foo(self: Pin<&mut Self>) {
|
||||
}
|
||||
}
|
||||
|
||||
fn foo(_: Pin<&mut Foo>) {
|
||||
}
|
||||
|
||||
|
@ -12,4 +17,9 @@ fn bar(mut x: Pin<&mut Foo>) {
|
|||
foo(x); //~ ERROR use of moved value: `x`
|
||||
}
|
||||
|
||||
fn baz(mut x: Pin<&mut Foo>) {
|
||||
x.foo();
|
||||
x.foo(); //~ ERROR use of moved value: `x`
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
error[E0382]: use of moved value: `x`
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:12:9
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:17:9
|
||||
|
|
||||
LL | fn bar(mut x: Pin<&mut Foo>) {
|
||||
| ----- move occurs because `x` has type `Pin<&mut Foo>`, which does not implement the `Copy` trait
|
||||
|
@ -9,13 +9,33 @@ LL | foo(x);
|
|||
| ^ value used here after move
|
||||
|
|
||||
note: consider changing this parameter type in function `foo` to borrow instead if owning the value isn't necessary
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:7:11
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:12:11
|
||||
|
|
||||
LL | fn foo(_: Pin<&mut Foo>) {
|
||||
| --- ^^^^^^^^^^^^^ this parameter takes ownership of the value
|
||||
| |
|
||||
| in this function
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
error[E0382]: use of moved value: `x`
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:22:5
|
||||
|
|
||||
LL | fn baz(mut x: Pin<&mut Foo>) {
|
||||
| ----- move occurs because `x` has type `Pin<&mut Foo>`, which does not implement the `Copy` trait
|
||||
LL | x.foo();
|
||||
| ----- `x` moved due to this method call
|
||||
LL | x.foo();
|
||||
| ^ value used here after move
|
||||
|
|
||||
note: `Foo::foo` takes ownership of the receiver `self`, which moves `x`
|
||||
--> $DIR/feature-gate-pin_ergonomics.rs:8:12
|
||||
|
|
||||
LL | fn foo(self: Pin<&mut Self>) {
|
||||
| ^^^^
|
||||
help: consider reborrowing the `Pin` instead of moving it
|
||||
|
|
||||
LL | x.as_mut().foo();
|
||||
| +++++++++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0382`.
|
||||
|
|
8
tests/ui/lint/unconditional_panic_promoted.rs
Normal file
8
tests/ui/lint/unconditional_panic_promoted.rs
Normal file
|
@ -0,0 +1,8 @@
|
|||
//@ build-fail
|
||||
|
||||
fn main() {
|
||||
// MIR encodes this as a reborrow from a promoted constant.
|
||||
// But the array lenth can still be gotten from the type.
|
||||
let slice = &[0, 1];
|
||||
let _ = slice[2]; //~ ERROR: this operation will panic at runtime [unconditional_panic]
|
||||
}
|
10
tests/ui/lint/unconditional_panic_promoted.stderr
Normal file
10
tests/ui/lint/unconditional_panic_promoted.stderr
Normal file
|
@ -0,0 +1,10 @@
|
|||
error: this operation will panic at runtime
|
||||
--> $DIR/unconditional_panic_promoted.rs:7:13
|
||||
|
|
||||
LL | let _ = slice[2];
|
||||
| ^^^^^^^^ index out of bounds: the length is 2 but the index is 2
|
||||
|
|
||||
= note: `#[deny(unconditional_panic)]` on by default
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
74
tests/ui/traits/missing-for-type-in-impl.e2015.stderr
Normal file
74
tests/ui/traits/missing-for-type-in-impl.e2015.stderr
Normal file
|
@ -0,0 +1,74 @@
|
|||
warning: trait objects without an explicit `dyn` are deprecated
|
||||
--> $DIR/missing-for-type-in-impl.rs:8:6
|
||||
|
|
||||
LL | impl Foo<i64> {
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
= note: `#[warn(bare_trait_objects)]` on by default
|
||||
help: if this is a dyn-compatible trait, use `dyn`
|
||||
|
|
||||
LL | impl dyn Foo<i64> {
|
||||
| +++
|
||||
help: you might have intended to implement this trait for a given type
|
||||
|
|
||||
LL | impl Foo<i64> for /* Type */ {
|
||||
| ++++++++++++++
|
||||
|
||||
warning: trait objects without an explicit `dyn` are deprecated
|
||||
--> $DIR/missing-for-type-in-impl.rs:8:6
|
||||
|
|
||||
LL | impl Foo<i64> {
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
help: if this is a dyn-compatible trait, use `dyn`
|
||||
|
|
||||
LL | impl dyn Foo<i64> {
|
||||
| +++
|
||||
help: you might have intended to implement this trait for a given type
|
||||
|
|
||||
LL | impl Foo<i64> for /* Type */ {
|
||||
| ++++++++++++++
|
||||
|
||||
error[E0038]: the trait `Foo` cannot be made into an object
|
||||
--> $DIR/missing-for-type-in-impl.rs:8:6
|
||||
|
|
||||
LL | impl Foo<i64> {
|
||||
| ^^^^^^^^ `Foo` cannot be made into an object
|
||||
|
|
||||
note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
|
||||
--> $DIR/missing-for-type-in-impl.rs:4:8
|
||||
|
|
||||
LL | trait Foo<T> {
|
||||
| --- this trait cannot be made into an object...
|
||||
LL | fn id(me: T) -> T;
|
||||
| ^^ ...because associated function `id` has no `self` parameter
|
||||
help: consider turning `id` into a method by giving it a `&self` argument
|
||||
|
|
||||
LL | fn id(&self, me: T) -> T;
|
||||
| ++++++
|
||||
help: alternatively, consider constraining `id` so it does not apply to trait objects
|
||||
|
|
||||
LL | fn id(me: T) -> T where Self: Sized;
|
||||
| +++++++++++++++++
|
||||
|
||||
error[E0277]: the trait bound `i64: Foo<i64>` is not satisfied
|
||||
--> $DIR/missing-for-type-in-impl.rs:19:19
|
||||
|
|
||||
LL | let x: i64 = <i64 as Foo<i64>>::id(10);
|
||||
| ^^^ the trait `Foo<i64>` is not implemented for `i64`
|
||||
|
|
||||
help: this trait has no implementations, consider adding one
|
||||
--> $DIR/missing-for-type-in-impl.rs:3:1
|
||||
|
|
||||
LL | trait Foo<T> {
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors; 2 warnings emitted
|
||||
|
||||
Some errors have detailed explanations: E0038, E0277.
|
||||
For more information about an error, try `rustc --explain E0038`.
|
31
tests/ui/traits/missing-for-type-in-impl.e2021.stderr
Normal file
31
tests/ui/traits/missing-for-type-in-impl.e2021.stderr
Normal file
|
@ -0,0 +1,31 @@
|
|||
error[E0277]: the trait bound `i64: Foo<i64>` is not satisfied
|
||||
--> $DIR/missing-for-type-in-impl.rs:19:19
|
||||
|
|
||||
LL | let x: i64 = <i64 as Foo<i64>>::id(10);
|
||||
| ^^^ the trait `Foo<i64>` is not implemented for `i64`
|
||||
|
|
||||
help: this trait has no implementations, consider adding one
|
||||
--> $DIR/missing-for-type-in-impl.rs:3:1
|
||||
|
|
||||
LL | trait Foo<T> {
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error[E0782]: trait objects must include the `dyn` keyword
|
||||
--> $DIR/missing-for-type-in-impl.rs:8:6
|
||||
|
|
||||
LL | impl Foo<i64> {
|
||||
| ^^^^^^^^
|
||||
|
|
||||
help: add `dyn` keyword before this trait
|
||||
|
|
||||
LL | impl dyn Foo<i64> {
|
||||
| +++
|
||||
help: you might have intended to implement this trait for a given type
|
||||
|
|
||||
LL | impl Foo<i64> for /* Type */ {
|
||||
| ++++++++++++++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0277, E0782.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
22
tests/ui/traits/missing-for-type-in-impl.rs
Normal file
22
tests/ui/traits/missing-for-type-in-impl.rs
Normal file
|
@ -0,0 +1,22 @@
|
|||
//@revisions: e2021 e2015
|
||||
//@[e2021]edition: 2021
|
||||
trait Foo<T> {
|
||||
fn id(me: T) -> T;
|
||||
}
|
||||
|
||||
/* note the "missing" for ... (in this case for i64, in order for this to compile) */
|
||||
impl Foo<i64> {
|
||||
//[e2021]~^ ERROR trait objects must include the `dyn` keyword
|
||||
//[e2015]~^^ WARNING trait objects without an explicit `dyn` are deprecated
|
||||
//[e2015]~| WARNING trait objects without an explicit `dyn` are deprecated
|
||||
//[e2015]~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
//[e2015]~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
//[e2015]~| ERROR the trait `Foo` cannot be made into an object
|
||||
fn id(me: i64) -> i64 {me}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x: i64 = <i64 as Foo<i64>>::id(10);
|
||||
//~^ ERROR the trait bound `i64: Foo<i64>` is not satisfied
|
||||
println!("{}", x);
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
// Make sure that when elaborating the principal of a dyn trait for projection predicates
|
||||
// we don't end up in a situation where we have an unconstrained late-bound lifetime in
|
||||
// the output of a projection.
|
||||
|
||||
// Fix for <https://github.com/rust-lang/rust/issues/130347>.
|
||||
|
||||
trait A<T>: B<T = T> {}
|
||||
|
||||
trait B {
|
||||
type T;
|
||||
}
|
||||
|
||||
struct Erase<T: ?Sized + B>(T::T);
|
||||
|
||||
fn main() {
|
||||
let x = {
|
||||
let x = String::from("hello");
|
||||
|
||||
Erase::<dyn for<'a> A<&'a _>>(x.as_str())
|
||||
//~^ ERROR binding for associated type `T` references lifetime `'a`, which does not appear in the trait input types
|
||||
};
|
||||
|
||||
dbg!(x.0);
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
error[E0582]: binding for associated type `T` references lifetime `'a`, which does not appear in the trait input types
|
||||
--> $DIR/elaborated-predicates-unconstrained-late-bound.rs:19:21
|
||||
|
|
||||
LL | trait A<T>: B<T = T> {}
|
||||
| ----- due to this supertrait
|
||||
...
|
||||
LL | Erase::<dyn for<'a> A<&'a _>>(x.as_str())
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0582`.
|
|
@ -13,7 +13,7 @@ trait SuperGeneric<'a> {
|
|||
}
|
||||
trait AnyGeneric<'a>: SuperGeneric<'a> {}
|
||||
trait FixedGeneric1<'a>: SuperGeneric<'a, Assoc2 = &'a u8> {}
|
||||
trait FixedGeneric2<'a>: Super<Assoc = &'a u8> {}
|
||||
// trait FixedGeneric2<'a>: Super<Assoc = &'a u8> {} // Unsound!
|
||||
trait FixedHrtb: for<'a> SuperGeneric<'a, Assoc2 = &'a u8> {}
|
||||
trait AnyDifferentBinders: for<'a> SuperGeneric<'a, Assoc2 = &'a u8> + Super {}
|
||||
trait FixedDifferentBinders: for<'a> SuperGeneric<'a, Assoc2 = &'a u8> + Super<Assoc = u8> {}
|
||||
|
@ -32,7 +32,7 @@ fn dyn_fixed_static(x: &dyn FixedStatic) { x } //~ERROR mismatched types
|
|||
fn dyn_super_generic(x: &dyn for<'a> SuperGeneric<'a, Assoc2 = &'a u8>) { x } //~ERROR mismatched types
|
||||
fn dyn_any_generic(x: &dyn for<'a> AnyGeneric<'a, Assoc2 = &'a u8>) { x } //~ERROR mismatched types
|
||||
fn dyn_fixed_generic1(x: &dyn for<'a> FixedGeneric1<'a>) { x } //~ERROR mismatched types
|
||||
fn dyn_fixed_generic2(x: &dyn for<'a> FixedGeneric2<'a>) { x } //~ERROR mismatched types
|
||||
// fn dyn_fixed_generic2(x: &dyn for<'a> FixedGeneric2<'a>) { x } // Unsound!
|
||||
fn dyn_fixed_generic_multi(x: &dyn for<'a> FixedGeneric1<'a, Assoc2 = &u8>) { x } //~ERROR mismatched types
|
||||
fn dyn_fixed_hrtb(x: &dyn FixedHrtb) { x } //~ERROR mismatched types
|
||||
fn dyn_any_different_binders(x: &dyn AnyDifferentBinders<Assoc = u8>) { x } //~ERROR mismatched types
|
||||
|
|
|
@ -106,17 +106,6 @@ LL | fn dyn_fixed_generic1(x: &dyn for<'a> FixedGeneric1<'a>) { x }
|
|||
= note: expected unit type `()`
|
||||
found reference `&dyn for<'a> FixedGeneric1<'a>`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/pretty.rs:35:60
|
||||
|
|
||||
LL | fn dyn_fixed_generic2(x: &dyn for<'a> FixedGeneric2<'a>) { x }
|
||||
| - ^ expected `()`, found `&dyn FixedGeneric2<'a>`
|
||||
| |
|
||||
| help: try adding a return type: `-> &dyn for<'a> FixedGeneric2<'a>`
|
||||
|
|
||||
= note: expected unit type `()`
|
||||
found reference `&dyn for<'a> FixedGeneric2<'a>`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/pretty.rs:36:79
|
||||
|
|
||||
|
@ -172,6 +161,6 @@ LL | fn dyn_has_gat(x: &dyn HasGat<u8, Assoc<bool> = ()>) { x }
|
|||
= note: expected unit type `()`
|
||||
found reference `&dyn HasGat<u8, Assoc<bool> = ()>`
|
||||
|
||||
error: aborting due to 15 previous errors; 1 warning emitted
|
||||
error: aborting due to 14 previous errors; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
|
Loading…
Add table
Reference in a new issue