Auto merge of #98486 - matthiaskrgr:rollup-u7m508x, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - #96412 (Windows: Iterative `remove_dir_all`) - #98126 (Mitigate MMIO stale data vulnerability) - #98149 (Set relocation_model to Pic on emscripten target) - #98194 (Leak pthread_{mutex,rwlock}_t if it's dropped while locked.) - #98298 (Point to type parameter definition when not finding variant, method and associated item) - #98311 (Reverse folder hierarchy) - #98401 (Add tracking issues to `--extern` option docs.) - #98429 (Use correct substs in enum discriminant cast) - #98431 (Suggest defining variable as mutable on `&mut _` type mismatch in pats) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
8aab472d52
@ -92,7 +92,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticRegionResolver<'a, 'tcx> {
|
||||
.borrow_mut()
|
||||
.unwrap_region_constraints()
|
||||
.opportunistic_resolve_var(rid);
|
||||
self.tcx().reuse_or_mk_region(r, ty::ReVar(resolved))
|
||||
TypeFolder::tcx(self).reuse_or_mk_region(r, ty::ReVar(resolved))
|
||||
}
|
||||
_ => r,
|
||||
}
|
||||
@ -179,15 +179,13 @@ struct FullTypeResolver<'a, 'tcx> {
|
||||
infcx: &'a InferCtxt<'a, 'tcx>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> TypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> {
|
||||
impl<'a, 'tcx> FallibleTypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> {
|
||||
type Error = FixupError<'tcx>;
|
||||
|
||||
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
|
||||
self.infcx.tcx
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> FallibleTypeFolder<'tcx> for FullTypeResolver<'a, 'tcx> {
|
||||
fn try_fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
if !t.needs_infer() {
|
||||
Ok(t) // micro-optimize -- if there is nothing in this type that this fold affects...
|
||||
|
@ -86,7 +86,7 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
|
||||
/// A convenient alternative to `try_fold_with` for use with infallible
|
||||
/// folders. Do not override this method, to ensure coherence with
|
||||
/// `try_fold_with`.
|
||||
fn fold_with<F: TypeFolder<'tcx, Error = !>>(self, folder: &mut F) -> Self {
|
||||
fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
self.try_fold_with(folder).into_ok()
|
||||
}
|
||||
|
||||
@ -216,7 +216,7 @@ pub trait TypeSuperFoldable<'tcx>: TypeFoldable<'tcx> {
|
||||
/// A convenient alternative to `try_super_fold_with` for use with
|
||||
/// infallible folders. Do not override this method, to ensure coherence
|
||||
/// with `try_super_fold_with`.
|
||||
fn super_fold_with<F: TypeFolder<'tcx, Error = !>>(self, folder: &mut F) -> Self {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
self.try_super_fold_with(folder).into_ok()
|
||||
}
|
||||
|
||||
@ -229,70 +229,46 @@ pub trait TypeSuperFoldable<'tcx>: TypeFoldable<'tcx> {
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy>;
|
||||
}
|
||||
|
||||
/// This trait is implemented for every folding traversal. There is a fold
|
||||
/// method defined for every type of interest. Each such method has a default
|
||||
/// that does an "identity" fold. Implementations of these methods often fall
|
||||
/// back to a `super_fold_with` method if the primary argument doesn't
|
||||
/// satisfy a particular condition.
|
||||
/// This trait is implemented for every infallible folding traversal. There is
|
||||
/// a fold method defined for every type of interest. Each such method has a
|
||||
/// default that does an "identity" fold. Implementations of these methods
|
||||
/// often fall back to a `super_fold_with` method if the primary argument
|
||||
/// doesn't satisfy a particular condition.
|
||||
///
|
||||
/// If this folder is fallible (and therefore its [`Error`][`TypeFolder::Error`]
|
||||
/// associated type is something other than the default `!`) then
|
||||
/// [`FallibleTypeFolder`] should be implemented manually. Otherwise,
|
||||
/// a blanket implementation of [`FallibleTypeFolder`] will defer to
|
||||
/// A blanket implementation of [`FallibleTypeFolder`] will defer to
|
||||
/// the infallible methods of this trait to ensure that the two APIs
|
||||
/// are coherent.
|
||||
pub trait TypeFolder<'tcx>: Sized {
|
||||
type Error = !;
|
||||
|
||||
pub trait TypeFolder<'tcx>: FallibleTypeFolder<'tcx, Error = !> {
|
||||
fn tcx<'a>(&'a self) -> TyCtxt<'tcx>;
|
||||
|
||||
fn fold_binder<T>(&mut self, t: Binder<'tcx, T>) -> Binder<'tcx, T>
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
Self: TypeFolder<'tcx, Error = !>,
|
||||
{
|
||||
t.super_fold_with(self)
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx>
|
||||
where
|
||||
Self: TypeFolder<'tcx, Error = !>,
|
||||
{
|
||||
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
|
||||
t.super_fold_with(self)
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx>
|
||||
where
|
||||
Self: TypeFolder<'tcx, Error = !>,
|
||||
{
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
r.super_fold_with(self)
|
||||
}
|
||||
|
||||
fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx>
|
||||
where
|
||||
Self: TypeFolder<'tcx, Error = !>,
|
||||
{
|
||||
fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> {
|
||||
c.super_fold_with(self)
|
||||
}
|
||||
|
||||
fn fold_unevaluated(&mut self, uv: ty::Unevaluated<'tcx>) -> ty::Unevaluated<'tcx>
|
||||
where
|
||||
Self: TypeFolder<'tcx, Error = !>,
|
||||
{
|
||||
fn fold_unevaluated(&mut self, uv: ty::Unevaluated<'tcx>) -> ty::Unevaluated<'tcx> {
|
||||
uv.super_fold_with(self)
|
||||
}
|
||||
|
||||
fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx>
|
||||
where
|
||||
Self: TypeFolder<'tcx, Error = !>,
|
||||
{
|
||||
fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
|
||||
p.super_fold_with(self)
|
||||
}
|
||||
|
||||
fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx>
|
||||
where
|
||||
Self: TypeFolder<'tcx, Error = !>,
|
||||
{
|
||||
fn fold_mir_const(&mut self, c: mir::ConstantKind<'tcx>) -> mir::ConstantKind<'tcx> {
|
||||
bug!("most type folders should not be folding MIR datastructures: {:?}", c)
|
||||
}
|
||||
}
|
||||
@ -304,7 +280,11 @@ pub trait TypeFolder<'tcx>: Sized {
|
||||
/// A blanket implementation of this trait (that defers to the relevant
|
||||
/// method of [`TypeFolder`]) is provided for all infallible folders in
|
||||
/// order to ensure the two APIs are coherent.
|
||||
pub trait FallibleTypeFolder<'tcx>: TypeFolder<'tcx> {
|
||||
pub trait FallibleTypeFolder<'tcx>: Sized {
|
||||
type Error;
|
||||
|
||||
fn tcx<'a>(&'a self) -> TyCtxt<'tcx>;
|
||||
|
||||
fn try_fold_binder<T>(&mut self, t: Binder<'tcx, T>) -> Result<Binder<'tcx, T>, Self::Error>
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
@ -350,45 +330,48 @@ pub trait FallibleTypeFolder<'tcx>: TypeFolder<'tcx> {
|
||||
// delegates to infallible methods to ensure coherence.
|
||||
impl<'tcx, F> FallibleTypeFolder<'tcx> for F
|
||||
where
|
||||
F: TypeFolder<'tcx, Error = !>,
|
||||
F: TypeFolder<'tcx>,
|
||||
{
|
||||
fn try_fold_binder<T>(&mut self, t: Binder<'tcx, T>) -> Result<Binder<'tcx, T>, Self::Error>
|
||||
type Error = !;
|
||||
|
||||
fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {
|
||||
TypeFolder::tcx(self)
|
||||
}
|
||||
|
||||
fn try_fold_binder<T>(&mut self, t: Binder<'tcx, T>) -> Result<Binder<'tcx, T>, !>
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
{
|
||||
Ok(self.fold_binder(t))
|
||||
}
|
||||
|
||||
fn try_fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
fn try_fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, !> {
|
||||
Ok(self.fold_ty(t))
|
||||
}
|
||||
|
||||
fn try_fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, Self::Error> {
|
||||
fn try_fold_region(&mut self, r: ty::Region<'tcx>) -> Result<ty::Region<'tcx>, !> {
|
||||
Ok(self.fold_region(r))
|
||||
}
|
||||
|
||||
fn try_fold_const(&mut self, c: ty::Const<'tcx>) -> Result<ty::Const<'tcx>, Self::Error> {
|
||||
fn try_fold_const(&mut self, c: ty::Const<'tcx>) -> Result<ty::Const<'tcx>, !> {
|
||||
Ok(self.fold_const(c))
|
||||
}
|
||||
|
||||
fn try_fold_unevaluated(
|
||||
&mut self,
|
||||
c: ty::Unevaluated<'tcx>,
|
||||
) -> Result<ty::Unevaluated<'tcx>, Self::Error> {
|
||||
) -> Result<ty::Unevaluated<'tcx>, !> {
|
||||
Ok(self.fold_unevaluated(c))
|
||||
}
|
||||
|
||||
fn try_fold_predicate(
|
||||
&mut self,
|
||||
p: ty::Predicate<'tcx>,
|
||||
) -> Result<ty::Predicate<'tcx>, Self::Error> {
|
||||
fn try_fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> Result<ty::Predicate<'tcx>, !> {
|
||||
Ok(self.fold_predicate(p))
|
||||
}
|
||||
|
||||
fn try_fold_mir_const(
|
||||
&mut self,
|
||||
c: mir::ConstantKind<'tcx>,
|
||||
) -> Result<mir::ConstantKind<'tcx>, Self::Error> {
|
||||
) -> Result<mir::ConstantKind<'tcx>, !> {
|
||||
Ok(self.fold_mir_const(c))
|
||||
}
|
||||
}
|
||||
|
@ -228,15 +228,13 @@ impl<'tcx> TryNormalizeAfterErasingRegionsFolder<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFolder<'tcx> for TryNormalizeAfterErasingRegionsFolder<'tcx> {
|
||||
impl<'tcx> FallibleTypeFolder<'tcx> for TryNormalizeAfterErasingRegionsFolder<'tcx> {
|
||||
type Error = NormalizationError<'tcx>;
|
||||
|
||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> FallibleTypeFolder<'tcx> for TryNormalizeAfterErasingRegionsFolder<'tcx> {
|
||||
fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
|
||||
match self.try_normalize_generic_arg_after_erasing_regions(ty.into()) {
|
||||
Ok(t) => Ok(t.expect_ty()),
|
||||
|
@ -705,7 +705,7 @@ impl<'a, 'tcx> SubstFolder<'a, 'tcx> {
|
||||
return val;
|
||||
}
|
||||
|
||||
let result = ty::fold::shift_vars(self.tcx(), val, self.binders_passed);
|
||||
let result = ty::fold::shift_vars(TypeFolder::tcx(self), val, self.binders_passed);
|
||||
debug!("shift_vars: shifted result = {:?}", result);
|
||||
|
||||
result
|
||||
|
@ -1,3 +1,4 @@
|
||||
use crate::thir::cx::region::Scope;
|
||||
use crate::thir::cx::Cx;
|
||||
use crate::thir::util::UserAnnotatedTyHelpers;
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
@ -158,6 +159,98 @@ impl<'tcx> Cx<'tcx> {
|
||||
Expr { temp_lifetime, ty: adjustment.target, span, kind }
|
||||
}
|
||||
|
||||
/// Lowers a cast expression.
|
||||
///
|
||||
/// Dealing with user type annotations is left to the caller.
|
||||
fn mirror_expr_cast(
|
||||
&mut self,
|
||||
source: &'tcx hir::Expr<'tcx>,
|
||||
temp_lifetime: Option<Scope>,
|
||||
span: Span,
|
||||
) -> ExprKind<'tcx> {
|
||||
let tcx = self.tcx;
|
||||
|
||||
// Check to see if this cast is a "coercion cast", where the cast is actually done
|
||||
// using a coercion (or is a no-op).
|
||||
if self.typeck_results().is_coercion_cast(source.hir_id) {
|
||||
// Convert the lexpr to a vexpr.
|
||||
ExprKind::Use { source: self.mirror_expr(source) }
|
||||
} else if self.typeck_results().expr_ty(source).is_region_ptr() {
|
||||
// Special cased so that we can type check that the element
|
||||
// type of the source matches the pointed to type of the
|
||||
// destination.
|
||||
ExprKind::Pointer {
|
||||
source: self.mirror_expr(source),
|
||||
cast: PointerCast::ArrayToPointer,
|
||||
}
|
||||
} else {
|
||||
// check whether this is casting an enum variant discriminant
|
||||
// to prevent cycles, we refer to the discriminant initializer
|
||||
// which is always an integer and thus doesn't need to know the
|
||||
// enum's layout (or its tag type) to compute it during const eval
|
||||
// Example:
|
||||
// enum Foo {
|
||||
// A,
|
||||
// B = A as isize + 4,
|
||||
// }
|
||||
// The correct solution would be to add symbolic computations to miri,
|
||||
// so we wouldn't have to compute and store the actual value
|
||||
|
||||
let hir::ExprKind::Path(ref qpath) = source.kind else {
|
||||
return ExprKind::Cast { source: self.mirror_expr(source)};
|
||||
};
|
||||
|
||||
let res = self.typeck_results().qpath_res(qpath, source.hir_id);
|
||||
let ty = self.typeck_results().node_type(source.hir_id);
|
||||
let ty::Adt(adt_def, substs) = ty.kind() else {
|
||||
return ExprKind::Cast { source: self.mirror_expr(source)};
|
||||
};
|
||||
|
||||
let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Const), variant_ctor_id) = res else {
|
||||
return ExprKind::Cast { source: self.mirror_expr(source)};
|
||||
};
|
||||
|
||||
let idx = adt_def.variant_index_with_ctor_id(variant_ctor_id);
|
||||
let (discr_did, discr_offset) = adt_def.discriminant_def_for_variant(idx);
|
||||
|
||||
use rustc_middle::ty::util::IntTypeExt;
|
||||
let ty = adt_def.repr().discr_type();
|
||||
let discr_ty = ty.to_ty(tcx);
|
||||
|
||||
let param_env_ty = self.param_env.and(discr_ty);
|
||||
let size = tcx
|
||||
.layout_of(param_env_ty)
|
||||
.unwrap_or_else(|e| {
|
||||
panic!("could not compute layout for {:?}: {:?}", param_env_ty, e)
|
||||
})
|
||||
.size;
|
||||
|
||||
let lit = ScalarInt::try_from_uint(discr_offset as u128, size).unwrap();
|
||||
let kind = ExprKind::NonHirLiteral { lit, user_ty: None };
|
||||
let offset = self.thir.exprs.push(Expr { temp_lifetime, ty: discr_ty, span, kind });
|
||||
|
||||
let source = match discr_did {
|
||||
// in case we are offsetting from a computed discriminant
|
||||
// and not the beginning of discriminants (which is always `0`)
|
||||
Some(did) => {
|
||||
let kind = ExprKind::NamedConst { def_id: did, substs, user_ty: None };
|
||||
let lhs =
|
||||
self.thir.exprs.push(Expr { temp_lifetime, ty: discr_ty, span, kind });
|
||||
let bin = ExprKind::Binary { op: BinOp::Add, lhs, rhs: offset };
|
||||
self.thir.exprs.push(Expr {
|
||||
temp_lifetime,
|
||||
ty: discr_ty,
|
||||
span: span,
|
||||
kind: bin,
|
||||
})
|
||||
}
|
||||
None => offset,
|
||||
};
|
||||
|
||||
ExprKind::Cast { source }
|
||||
}
|
||||
}
|
||||
|
||||
fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'tcx> {
|
||||
let tcx = self.tcx;
|
||||
let expr_ty = self.typeck_results().expr_ty(expr);
|
||||
@ -604,98 +697,7 @@ impl<'tcx> Cx<'tcx> {
|
||||
expr, cast_ty.hir_id, user_ty,
|
||||
);
|
||||
|
||||
// Check to see if this cast is a "coercion cast", where the cast is actually done
|
||||
// using a coercion (or is a no-op).
|
||||
let cast = if self.typeck_results().is_coercion_cast(source.hir_id) {
|
||||
// Convert the lexpr to a vexpr.
|
||||
ExprKind::Use { source: self.mirror_expr(source) }
|
||||
} else if self.typeck_results().expr_ty(source).is_region_ptr() {
|
||||
// Special cased so that we can type check that the element
|
||||
// type of the source matches the pointed to type of the
|
||||
// destination.
|
||||
ExprKind::Pointer {
|
||||
source: self.mirror_expr(source),
|
||||
cast: PointerCast::ArrayToPointer,
|
||||
}
|
||||
} else {
|
||||
// check whether this is casting an enum variant discriminant
|
||||
// to prevent cycles, we refer to the discriminant initializer
|
||||
// which is always an integer and thus doesn't need to know the
|
||||
// enum's layout (or its tag type) to compute it during const eval
|
||||
// Example:
|
||||
// enum Foo {
|
||||
// A,
|
||||
// B = A as isize + 4,
|
||||
// }
|
||||
// The correct solution would be to add symbolic computations to miri,
|
||||
// so we wouldn't have to compute and store the actual value
|
||||
let var = if let hir::ExprKind::Path(ref qpath) = source.kind {
|
||||
let res = self.typeck_results().qpath_res(qpath, source.hir_id);
|
||||
self.typeck_results().node_type(source.hir_id).ty_adt_def().and_then(
|
||||
|adt_def| match res {
|
||||
Res::Def(
|
||||
DefKind::Ctor(CtorOf::Variant, CtorKind::Const),
|
||||
variant_ctor_id,
|
||||
) => {
|
||||
let idx = adt_def.variant_index_with_ctor_id(variant_ctor_id);
|
||||
let (d, o) = adt_def.discriminant_def_for_variant(idx);
|
||||
use rustc_middle::ty::util::IntTypeExt;
|
||||
let ty = adt_def.repr().discr_type();
|
||||
let ty = ty.to_ty(tcx);
|
||||
Some((d, o, ty))
|
||||
}
|
||||
_ => None,
|
||||
},
|
||||
)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let source = if let Some((did, offset, var_ty)) = var {
|
||||
let param_env_ty = self.param_env.and(var_ty);
|
||||
let size = tcx
|
||||
.layout_of(param_env_ty)
|
||||
.unwrap_or_else(|e| {
|
||||
panic!("could not compute layout for {:?}: {:?}", param_env_ty, e)
|
||||
})
|
||||
.size;
|
||||
let lit = ScalarInt::try_from_uint(offset as u128, size).unwrap();
|
||||
let kind = ExprKind::NonHirLiteral { lit, user_ty: None };
|
||||
let offset = self.thir.exprs.push(Expr {
|
||||
temp_lifetime,
|
||||
ty: var_ty,
|
||||
span: expr.span,
|
||||
kind,
|
||||
});
|
||||
match did {
|
||||
Some(did) => {
|
||||
// in case we are offsetting from a computed discriminant
|
||||
// and not the beginning of discriminants (which is always `0`)
|
||||
let substs = InternalSubsts::identity_for_item(tcx, did);
|
||||
let kind =
|
||||
ExprKind::NamedConst { def_id: did, substs, user_ty: None };
|
||||
let lhs = self.thir.exprs.push(Expr {
|
||||
temp_lifetime,
|
||||
ty: var_ty,
|
||||
span: expr.span,
|
||||
kind,
|
||||
});
|
||||
let bin = ExprKind::Binary { op: BinOp::Add, lhs, rhs: offset };
|
||||
self.thir.exprs.push(Expr {
|
||||
temp_lifetime,
|
||||
ty: var_ty,
|
||||
span: expr.span,
|
||||
kind: bin,
|
||||
})
|
||||
}
|
||||
None => offset,
|
||||
}
|
||||
} else {
|
||||
self.mirror_expr(source)
|
||||
};
|
||||
|
||||
ExprKind::Cast { source: source }
|
||||
};
|
||||
let cast = self.mirror_expr_cast(*source, temp_lifetime, expr.span);
|
||||
|
||||
if let Some(user_ty) = user_ty {
|
||||
// NOTE: Creating a new Expr and wrapping a Cast inside of it may be
|
||||
|
@ -1,5 +1,5 @@
|
||||
use super::{cvs, wasm_base};
|
||||
use super::{LinkArgs, LinkerFlavor, PanicStrategy, Target, TargetOptions};
|
||||
use super::{LinkArgs, LinkerFlavor, PanicStrategy, RelocModel, Target, TargetOptions};
|
||||
|
||||
pub fn target() -> Target {
|
||||
let mut options = wasm_base::options();
|
||||
@ -26,6 +26,7 @@ pub fn target() -> Target {
|
||||
// functionality, and a .wasm file.
|
||||
exe_suffix: ".js".into(),
|
||||
linker: None,
|
||||
relocation_model: RelocModel::Pic,
|
||||
panic_strategy: PanicStrategy::Unwind,
|
||||
no_default_libraries: false,
|
||||
post_link_args,
|
||||
|
@ -12,7 +12,7 @@ use rustc_data_structures::sso::SsoHashMap;
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_infer::traits::Normalized;
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable};
|
||||
use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable};
|
||||
use rustc_middle::ty::subst::Subst;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitor};
|
||||
|
||||
@ -162,15 +162,13 @@ struct QueryNormalizer<'cx, 'tcx> {
|
||||
universes: Vec<Option<ty::UniverseIndex>>,
|
||||
}
|
||||
|
||||
impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
||||
impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
||||
type Error = NoSolution;
|
||||
|
||||
fn tcx<'c>(&'c self) -> TyCtxt<'tcx> {
|
||||
self.infcx.tcx
|
||||
}
|
||||
}
|
||||
|
||||
impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
||||
fn try_fold_binder<T: TypeFoldable<'tcx>>(
|
||||
&mut self,
|
||||
t: ty::Binder<'tcx, T>,
|
||||
|
@ -346,19 +346,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(def) = actual.ty_adt_def() {
|
||||
if let Some(full_sp) = tcx.hir().span_if_local(def.did()) {
|
||||
let def_sp = tcx.sess.source_map().guess_head_span(full_sp);
|
||||
err.span_label(
|
||||
def_sp,
|
||||
format!(
|
||||
"{} `{}` not found {}",
|
||||
item_kind,
|
||||
item_name,
|
||||
if def.is_enum() && !is_method { "here" } else { "for this" }
|
||||
),
|
||||
);
|
||||
let ty_span = match actual.kind() {
|
||||
ty::Param(param_type) => {
|
||||
let generics = self.tcx.generics_of(self.body_id.owner.to_def_id());
|
||||
let type_param = generics.type_param(param_type, self.tcx);
|
||||
Some(self.tcx.def_span(type_param.def_id))
|
||||
}
|
||||
ty::Adt(def, _) if def.did().is_local() => {
|
||||
tcx.def_ident_span(def.did()).map(|span| span)
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
|
||||
if let Some(span) = ty_span {
|
||||
err.span_label(
|
||||
span,
|
||||
format!(
|
||||
"{item_kind} `{item_name}` not found for this {}",
|
||||
actual.prefix_string(self.tcx)
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if self.is_fn_ty(rcvr_ty, span) {
|
||||
@ -1951,9 +1958,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
)
|
||||
};
|
||||
// Obtain the span for `param` and use it for a structured suggestion.
|
||||
if let (Some(param), Some(table)) = (param_type, self.in_progress_typeck_results) {
|
||||
let table_owner = table.borrow().hir_owner;
|
||||
let generics = self.tcx.generics_of(table_owner.to_def_id());
|
||||
if let Some(param) = param_type {
|
||||
let generics = self.tcx.generics_of(self.body_id.owner.to_def_id());
|
||||
let type_param = generics.type_param(param, self.tcx);
|
||||
let hir = self.tcx.hir();
|
||||
if let Some(def_id) = type_param.def_id.as_local() {
|
||||
|
@ -663,6 +663,46 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
ast::Mutability::Not => "",
|
||||
};
|
||||
|
||||
let mut_var_suggestion = 'block: {
|
||||
if !matches!(mutbl, ast::Mutability::Mut) {
|
||||
break 'block None;
|
||||
}
|
||||
|
||||
let ident_kind = match binding_parent {
|
||||
hir::Node::Param(_) => "parameter",
|
||||
hir::Node::Local(_) => "variable",
|
||||
hir::Node::Arm(_) => "binding",
|
||||
|
||||
// Provide diagnostics only if the parent pattern is struct-like,
|
||||
// i.e. where `mut binding` makes sense
|
||||
hir::Node::Pat(Pat { kind, .. }) => match kind {
|
||||
PatKind::Struct(..)
|
||||
| PatKind::TupleStruct(..)
|
||||
| PatKind::Or(..)
|
||||
| PatKind::Tuple(..)
|
||||
| PatKind::Slice(..) => "binding",
|
||||
|
||||
PatKind::Wild
|
||||
| PatKind::Binding(..)
|
||||
| PatKind::Path(..)
|
||||
| PatKind::Box(..)
|
||||
| PatKind::Ref(..)
|
||||
| PatKind::Lit(..)
|
||||
| PatKind::Range(..) => break 'block None,
|
||||
},
|
||||
|
||||
// Don't provide suggestions in other cases
|
||||
_ => break 'block None,
|
||||
};
|
||||
|
||||
Some((
|
||||
pat.span,
|
||||
format!("to declare a mutable {ident_kind} use"),
|
||||
format!("mut {binding}"),
|
||||
))
|
||||
|
||||
};
|
||||
|
||||
match binding_parent {
|
||||
// Check that there is explicit type (ie this is not a closure param with inferred type)
|
||||
// so we don't suggest moving something to the type that does not exist
|
||||
@ -675,6 +715,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
],
|
||||
Applicability::MachineApplicable
|
||||
);
|
||||
|
||||
if let Some((sp, msg, sugg)) = mut_var_suggestion {
|
||||
err.span_note(sp, format!("{msg}: `{sugg}`"));
|
||||
}
|
||||
}
|
||||
hir::Node::Param(_) | hir::Node::Arm(_) | hir::Node::Pat(_) => {
|
||||
// rely on match ergonomics or it might be nested `&&pat`
|
||||
@ -684,6 +728,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
"",
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
|
||||
if let Some((sp, msg, sugg)) = mut_var_suggestion {
|
||||
err.span_note(sp, format!("{msg}: `{sugg}`"));
|
||||
}
|
||||
}
|
||||
_ if let Some((sp, msg, sugg)) = mut_var_suggestion => {
|
||||
err.span_suggestion(sp, msg, sugg, Applicability::MachineApplicable);
|
||||
}
|
||||
_ => {} // don't provide suggestions in other cases #55175
|
||||
}
|
||||
|
@ -1,13 +1,16 @@
|
||||
#![allow(unused)]
|
||||
|
||||
use crate::arch::asm;
|
||||
use crate::cell::UnsafeCell;
|
||||
use crate::cmp;
|
||||
use crate::convert::TryInto;
|
||||
use crate::mem;
|
||||
use crate::ops::{CoerceUnsized, Deref, DerefMut, Index, IndexMut};
|
||||
use crate::ptr::{self, NonNull};
|
||||
use crate::slice;
|
||||
use crate::slice::SliceIndex;
|
||||
|
||||
use super::super::mem::is_user_range;
|
||||
use super::super::mem::{is_enclave_range, is_user_range};
|
||||
use fortanix_sgx_abi::*;
|
||||
|
||||
/// A type that can be safely read from or written to userspace.
|
||||
@ -210,7 +213,9 @@ where
|
||||
unsafe {
|
||||
// Mustn't call alloc with size 0.
|
||||
let ptr = if size > 0 {
|
||||
rtunwrap!(Ok, super::alloc(size, T::align_of())) as _
|
||||
// `copy_to_userspace` is more efficient when data is 8-byte aligned
|
||||
let alignment = cmp::max(T::align_of(), 8);
|
||||
rtunwrap!(Ok, super::alloc(size, alignment)) as _
|
||||
} else {
|
||||
T::align_of() as _ // dangling pointer ok for size 0
|
||||
};
|
||||
@ -225,13 +230,9 @@ where
|
||||
/// Copies `val` into freshly allocated space in user memory.
|
||||
pub fn new_from_enclave(val: &T) -> Self {
|
||||
unsafe {
|
||||
let ret = Self::new_uninit_bytes(mem::size_of_val(val));
|
||||
ptr::copy(
|
||||
val as *const T as *const u8,
|
||||
ret.0.as_ptr() as *mut u8,
|
||||
mem::size_of_val(val),
|
||||
);
|
||||
ret
|
||||
let mut user = Self::new_uninit_bytes(mem::size_of_val(val));
|
||||
user.copy_from_enclave(val);
|
||||
user
|
||||
}
|
||||
}
|
||||
|
||||
@ -304,6 +305,105 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Copies `len` bytes of data from enclave pointer `src` to userspace `dst`
|
||||
///
|
||||
/// This function mitigates stale data vulnerabilities by ensuring all writes to untrusted memory are either:
|
||||
/// - preceded by the VERW instruction and followed by the MFENCE; LFENCE instruction sequence
|
||||
/// - or are in multiples of 8 bytes, aligned to an 8-byte boundary
|
||||
///
|
||||
/// # Panics
|
||||
/// This function panics if:
|
||||
///
|
||||
/// * The `src` pointer is null
|
||||
/// * The `dst` pointer is null
|
||||
/// * The `src` memory range is not in enclave memory
|
||||
/// * The `dst` memory range is not in user memory
|
||||
///
|
||||
/// # References
|
||||
/// - https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00615.html
|
||||
/// - https://www.intel.com/content/www/us/en/developer/articles/technical/software-security-guidance/technical-documentation/processor-mmio-stale-data-vulnerabilities.html#inpage-nav-3-2-2
|
||||
pub(crate) unsafe fn copy_to_userspace(src: *const u8, dst: *mut u8, len: usize) {
|
||||
unsafe fn copy_bytewise_to_userspace(src: *const u8, dst: *mut u8, len: usize) {
|
||||
unsafe {
|
||||
let mut seg_sel: u16 = 0;
|
||||
for off in 0..len {
|
||||
asm!("
|
||||
mov %ds, ({seg_sel})
|
||||
verw ({seg_sel})
|
||||
movb {val}, ({dst})
|
||||
mfence
|
||||
lfence
|
||||
",
|
||||
val = in(reg_byte) *src.offset(off as isize),
|
||||
dst = in(reg) dst.offset(off as isize),
|
||||
seg_sel = in(reg) &mut seg_sel,
|
||||
options(nostack, att_syntax)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn copy_aligned_quadwords_to_userspace(src: *const u8, dst: *mut u8, len: usize) {
|
||||
unsafe {
|
||||
asm!(
|
||||
"rep movsq (%rsi), (%rdi)",
|
||||
inout("rcx") len / 8 => _,
|
||||
inout("rdi") dst => _,
|
||||
inout("rsi") src => _,
|
||||
options(att_syntax, nostack, preserves_flags)
|
||||
);
|
||||
}
|
||||
}
|
||||
assert!(!src.is_null());
|
||||
assert!(!dst.is_null());
|
||||
assert!(is_enclave_range(src, len));
|
||||
assert!(is_user_range(dst, len));
|
||||
assert!(len < isize::MAX as usize);
|
||||
assert!(!(src as usize).overflowing_add(len).1);
|
||||
assert!(!(dst as usize).overflowing_add(len).1);
|
||||
|
||||
if len < 8 {
|
||||
// Can't align on 8 byte boundary: copy safely byte per byte
|
||||
unsafe {
|
||||
copy_bytewise_to_userspace(src, dst, len);
|
||||
}
|
||||
} else if len % 8 == 0 && dst as usize % 8 == 0 {
|
||||
// Copying 8-byte aligned quadwords: copy quad word per quad word
|
||||
unsafe {
|
||||
copy_aligned_quadwords_to_userspace(src, dst, len);
|
||||
}
|
||||
} else {
|
||||
// Split copies into three parts:
|
||||
// +--------+
|
||||
// | small0 | Chunk smaller than 8 bytes
|
||||
// +--------+
|
||||
// | big | Chunk 8-byte aligned, and size a multiple of 8 bytes
|
||||
// +--------+
|
||||
// | small1 | Chunk smaller than 8 bytes
|
||||
// +--------+
|
||||
|
||||
unsafe {
|
||||
// Copy small0
|
||||
let small0_size = (8 - dst as usize % 8) as u8;
|
||||
let small0_src = src;
|
||||
let small0_dst = dst;
|
||||
copy_bytewise_to_userspace(small0_src as _, small0_dst, small0_size as _);
|
||||
|
||||
// Copy big
|
||||
let small1_size = ((len - small0_size as usize) % 8) as u8;
|
||||
let big_size = len - small0_size as usize - small1_size as usize;
|
||||
let big_src = src.offset(small0_size as _);
|
||||
let big_dst = dst.offset(small0_size as _);
|
||||
copy_aligned_quadwords_to_userspace(big_src as _, big_dst, big_size);
|
||||
|
||||
// Copy small1
|
||||
let small1_src = src.offset(big_size as isize + small0_size as isize);
|
||||
let small1_dst = dst.offset(big_size as isize + small0_size as isize);
|
||||
copy_bytewise_to_userspace(small1_src, small1_dst, small1_size as _);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "sgx_platform", issue = "56975")]
|
||||
impl<T: ?Sized> UserRef<T>
|
||||
where
|
||||
@ -352,7 +452,7 @@ where
|
||||
pub fn copy_from_enclave(&mut self, val: &T) {
|
||||
unsafe {
|
||||
assert_eq!(mem::size_of_val(val), mem::size_of_val(&*self.0.get()));
|
||||
ptr::copy(
|
||||
copy_to_userspace(
|
||||
val as *const T as *const u8,
|
||||
self.0.get() as *mut T as *mut u8,
|
||||
mem::size_of_val(val),
|
||||
|
@ -6,6 +6,8 @@ use crate::time::{Duration, Instant};
|
||||
pub(crate) mod alloc;
|
||||
#[macro_use]
|
||||
pub(crate) mod raw;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
use self::raw::*;
|
||||
|
||||
|
30
library/std/src/sys/sgx/abi/usercalls/tests.rs
Normal file
30
library/std/src/sys/sgx/abi/usercalls/tests.rs
Normal file
@ -0,0 +1,30 @@
|
||||
use super::alloc::copy_to_userspace;
|
||||
use super::alloc::User;
|
||||
|
||||
#[test]
|
||||
fn test_copy_function() {
|
||||
let mut src = [0u8; 100];
|
||||
let mut dst = User::<[u8]>::uninitialized(100);
|
||||
|
||||
for i in 0..src.len() {
|
||||
src[i] = i as _;
|
||||
}
|
||||
|
||||
for size in 0..48 {
|
||||
// For all possible alignment
|
||||
for offset in 0..8 {
|
||||
// overwrite complete dst
|
||||
dst.copy_from_enclave(&[0u8; 100]);
|
||||
|
||||
// Copy src[0..size] to dst + offset
|
||||
unsafe { copy_to_userspace(src.as_ptr(), dst.as_mut_ptr().offset(offset), size) };
|
||||
|
||||
// Verify copy
|
||||
for byte in 0..size {
|
||||
unsafe {
|
||||
assert_eq!(*dst.as_ptr().offset(offset + byte as isize), src[byte as usize]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
use crate::cell::UnsafeCell;
|
||||
use crate::mem::MaybeUninit;
|
||||
use crate::mem::{forget, MaybeUninit};
|
||||
use crate::sys::cvt_nz;
|
||||
use crate::sys_common::lazy_box::{LazyBox, LazyInit};
|
||||
|
||||
@ -23,6 +23,24 @@ impl LazyInit for Mutex {
|
||||
unsafe { mutex.init() };
|
||||
mutex
|
||||
}
|
||||
|
||||
fn destroy(mutex: Box<Self>) {
|
||||
// We're not allowed to pthread_mutex_destroy a locked mutex,
|
||||
// so check first if it's unlocked.
|
||||
if unsafe { mutex.try_lock() } {
|
||||
unsafe { mutex.unlock() };
|
||||
drop(mutex);
|
||||
} else {
|
||||
// The mutex is locked. This happens if a MutexGuard is leaked.
|
||||
// In this case, we just leak the Mutex too.
|
||||
forget(mutex);
|
||||
}
|
||||
}
|
||||
|
||||
fn cancel_init(_: Box<Self>) {
|
||||
// In this case, we can just drop it without any checks,
|
||||
// since it cannot have been locked yet.
|
||||
}
|
||||
}
|
||||
|
||||
impl Mutex {
|
||||
|
@ -1,4 +1,5 @@
|
||||
use crate::cell::UnsafeCell;
|
||||
use crate::mem::forget;
|
||||
use crate::sync::atomic::{AtomicUsize, Ordering};
|
||||
use crate::sys_common::lazy_box::{LazyBox, LazyInit};
|
||||
|
||||
@ -17,6 +18,21 @@ impl LazyInit for RwLock {
|
||||
fn init() -> Box<Self> {
|
||||
Box::new(Self::new())
|
||||
}
|
||||
|
||||
fn destroy(mut rwlock: Box<Self>) {
|
||||
// We're not allowed to pthread_rwlock_destroy a locked rwlock,
|
||||
// so check first if it's unlocked.
|
||||
if *rwlock.write_locked.get_mut() || *rwlock.num_readers.get_mut() != 0 {
|
||||
// The rwlock is locked. This happens if a RwLock{Read,Write}Guard is leaked.
|
||||
// In this case, we just leak the RwLock too.
|
||||
forget(rwlock);
|
||||
}
|
||||
}
|
||||
|
||||
fn cancel_init(_: Box<Self>) {
|
||||
// In this case, we can just drop it without any checks,
|
||||
// since it cannot have been locked yet.
|
||||
}
|
||||
}
|
||||
|
||||
impl RwLock {
|
||||
|
@ -13,6 +13,7 @@ use crate::sys::handle::Handle;
|
||||
use crate::sys::time::SystemTime;
|
||||
use crate::sys::{c, cvt};
|
||||
use crate::sys_common::{AsInner, FromInner, IntoInner};
|
||||
use crate::thread;
|
||||
|
||||
use super::path::maybe_verbatim;
|
||||
use super::to_u16s;
|
||||
@ -679,7 +680,7 @@ impl<'a> DirBuffIter<'a> {
|
||||
}
|
||||
}
|
||||
impl<'a> Iterator for DirBuffIter<'a> {
|
||||
type Item = &'a [u16];
|
||||
type Item = (&'a [u16], bool);
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
use crate::mem::size_of;
|
||||
let buffer = &self.buffer?[self.cursor..];
|
||||
@ -688,14 +689,16 @@ impl<'a> Iterator for DirBuffIter<'a> {
|
||||
// SAFETY: The buffer contains a `FILE_ID_BOTH_DIR_INFO` struct but the
|
||||
// last field (the file name) is unsized. So an offset has to be
|
||||
// used to get the file name slice.
|
||||
let (name, next_entry) = unsafe {
|
||||
let (name, is_directory, next_entry) = unsafe {
|
||||
let info = buffer.as_ptr().cast::<c::FILE_ID_BOTH_DIR_INFO>();
|
||||
let next_entry = (*info).NextEntryOffset as usize;
|
||||
let name = crate::slice::from_raw_parts(
|
||||
(*info).FileName.as_ptr().cast::<u16>(),
|
||||
(*info).FileNameLength as usize / size_of::<u16>(),
|
||||
);
|
||||
(name, next_entry)
|
||||
let is_directory = ((*info).FileAttributes & c::FILE_ATTRIBUTE_DIRECTORY) != 0;
|
||||
|
||||
(name, is_directory, next_entry)
|
||||
};
|
||||
|
||||
if next_entry == 0 {
|
||||
@ -708,7 +711,7 @@ impl<'a> Iterator for DirBuffIter<'a> {
|
||||
const DOT: u16 = b'.' as u16;
|
||||
match name {
|
||||
[DOT] | [DOT, DOT] => self.next(),
|
||||
_ => Some(name),
|
||||
_ => Some((name, is_directory)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -993,89 +996,92 @@ pub fn remove_dir_all(path: &Path) -> io::Result<()> {
|
||||
if (file.basic_info()?.FileAttributes & c::FILE_ATTRIBUTE_DIRECTORY) == 0 {
|
||||
return Err(io::Error::from_raw_os_error(c::ERROR_DIRECTORY as _));
|
||||
}
|
||||
let mut delete: fn(&File) -> io::Result<()> = File::posix_delete;
|
||||
let result = match delete(&file) {
|
||||
Err(e) if e.kind() == io::ErrorKind::DirectoryNotEmpty => {
|
||||
match remove_dir_all_recursive(&file, delete) {
|
||||
// Return unexpected errors.
|
||||
Err(e) if e.kind() != io::ErrorKind::DirectoryNotEmpty => return Err(e),
|
||||
result => result,
|
||||
|
||||
match remove_dir_all_iterative(&file, File::posix_delete) {
|
||||
Err(e) => {
|
||||
if let Some(code) = e.raw_os_error() {
|
||||
match code as u32 {
|
||||
// If POSIX delete is not supported for this filesystem then fallback to win32 delete.
|
||||
c::ERROR_NOT_SUPPORTED
|
||||
| c::ERROR_INVALID_FUNCTION
|
||||
| c::ERROR_INVALID_PARAMETER => {
|
||||
remove_dir_all_iterative(&file, File::win32_delete)
|
||||
}
|
||||
_ => Err(e),
|
||||
}
|
||||
} else {
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
// If POSIX delete is not supported for this filesystem then fallback to win32 delete.
|
||||
Err(e)
|
||||
if e.raw_os_error() == Some(c::ERROR_NOT_SUPPORTED as i32)
|
||||
|| e.raw_os_error() == Some(c::ERROR_INVALID_PARAMETER as i32) =>
|
||||
{
|
||||
delete = File::win32_delete;
|
||||
Err(e)
|
||||
}
|
||||
result => result,
|
||||
};
|
||||
if result.is_ok() {
|
||||
Ok(())
|
||||
} else {
|
||||
// This is a fallback to make sure the directory is actually deleted.
|
||||
// Otherwise this function is prone to failing with `DirectoryNotEmpty`
|
||||
// due to possible delays between marking a file for deletion and the
|
||||
// file actually being deleted from the filesystem.
|
||||
//
|
||||
// So we retry a few times before giving up.
|
||||
for _ in 0..5 {
|
||||
match remove_dir_all_recursive(&file, delete) {
|
||||
Err(e) if e.kind() == io::ErrorKind::DirectoryNotEmpty => {}
|
||||
result => return result,
|
||||
}
|
||||
}
|
||||
// Try one last time.
|
||||
delete(&file)
|
||||
ok => ok,
|
||||
}
|
||||
}
|
||||
|
||||
fn remove_dir_all_recursive(f: &File, delete: fn(&File) -> io::Result<()>) -> io::Result<()> {
|
||||
fn remove_dir_all_iterative(f: &File, delete: fn(&File) -> io::Result<()>) -> io::Result<()> {
|
||||
// When deleting files we may loop this many times when certain error conditions occur.
|
||||
// This allows remove_dir_all to succeed when the error is temporary.
|
||||
const MAX_RETRIES: u32 = 10;
|
||||
|
||||
let mut buffer = DirBuff::new();
|
||||
let mut restart = true;
|
||||
// Fill the buffer and iterate the entries.
|
||||
while f.fill_dir_buff(&mut buffer, restart)? {
|
||||
for name in buffer.iter() {
|
||||
// Open the file without following symlinks and try deleting it.
|
||||
// We try opening will all needed permissions and if that is denied
|
||||
// fallback to opening without `FILE_LIST_DIRECTORY` permission.
|
||||
// Note `SYNCHRONIZE` permission is needed for synchronous access.
|
||||
let mut result =
|
||||
open_link_no_reparse(&f, name, c::SYNCHRONIZE | c::DELETE | c::FILE_LIST_DIRECTORY);
|
||||
if matches!(&result, Err(e) if e.kind() == io::ErrorKind::PermissionDenied) {
|
||||
result = open_link_no_reparse(&f, name, c::SYNCHRONIZE | c::DELETE);
|
||||
}
|
||||
match result {
|
||||
Ok(file) => match delete(&file) {
|
||||
Err(e) if e.kind() == io::ErrorKind::DirectoryNotEmpty => {
|
||||
// Iterate the directory's files.
|
||||
// Ignore `DirectoryNotEmpty` errors here. They will be
|
||||
// caught when `remove_dir_all` tries to delete the top
|
||||
// level directory. It can then decide if to retry or not.
|
||||
match remove_dir_all_recursive(&file, delete) {
|
||||
Err(e) if e.kind() == io::ErrorKind::DirectoryNotEmpty => {}
|
||||
result => result?,
|
||||
}
|
||||
let mut dirlist = vec![f.duplicate()?];
|
||||
|
||||
// FIXME: This is a hack so we can push to the dirlist vec after borrowing from it.
|
||||
fn copy_handle(f: &File) -> mem::ManuallyDrop<File> {
|
||||
unsafe { mem::ManuallyDrop::new(File::from_raw_handle(f.as_raw_handle())) }
|
||||
}
|
||||
|
||||
while let Some(dir) = dirlist.last() {
|
||||
let dir = copy_handle(dir);
|
||||
|
||||
// Fill the buffer and iterate the entries.
|
||||
let more_data = dir.fill_dir_buff(&mut buffer, false)?;
|
||||
for (name, is_directory) in buffer.iter() {
|
||||
if is_directory {
|
||||
let child_dir = open_link_no_reparse(
|
||||
&dir,
|
||||
name,
|
||||
c::SYNCHRONIZE | c::DELETE | c::FILE_LIST_DIRECTORY,
|
||||
)?;
|
||||
dirlist.push(child_dir);
|
||||
} else {
|
||||
for i in 1..=MAX_RETRIES {
|
||||
let result = open_link_no_reparse(&dir, name, c::SYNCHRONIZE | c::DELETE);
|
||||
match result {
|
||||
Ok(f) => delete(&f)?,
|
||||
// Already deleted, so skip.
|
||||
Err(e) if e.kind() == io::ErrorKind::NotFound => break,
|
||||
// Retry a few times if the file is locked or a delete is already in progress.
|
||||
Err(e)
|
||||
if i < MAX_RETRIES
|
||||
&& (e.raw_os_error() == Some(c::ERROR_DELETE_PENDING as _)
|
||||
|| e.raw_os_error()
|
||||
== Some(c::ERROR_SHARING_VIOLATION as _)) => {}
|
||||
// Otherwise return the error.
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
result => result?,
|
||||
},
|
||||
// Ignore error if a delete is already in progress or the file
|
||||
// has already been deleted. It also ignores sharing violations
|
||||
// (where a file is locked by another process) as these are
|
||||
// usually temporary.
|
||||
Err(e)
|
||||
if e.raw_os_error() == Some(c::ERROR_DELETE_PENDING as _)
|
||||
|| e.kind() == io::ErrorKind::NotFound
|
||||
|| e.raw_os_error() == Some(c::ERROR_SHARING_VIOLATION as _) => {}
|
||||
Err(e) => return Err(e),
|
||||
thread::yield_now();
|
||||
}
|
||||
}
|
||||
}
|
||||
// If there were no more files then delete the directory.
|
||||
if !more_data {
|
||||
if let Some(dir) = dirlist.pop() {
|
||||
// Retry deleting a few times in case we need to wait for a file to be deleted.
|
||||
for i in 1..=MAX_RETRIES {
|
||||
let result = delete(&dir);
|
||||
if let Err(e) = result {
|
||||
if i == MAX_RETRIES || e.kind() != io::ErrorKind::DirectoryNotEmpty {
|
||||
return Err(e);
|
||||
}
|
||||
thread::yield_now();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Continue reading directory entries without restarting from the beginning,
|
||||
restart = false;
|
||||
}
|
||||
delete(&f)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn readlink(path: &Path) -> io::Result<PathBuf> {
|
||||
|
@ -21,8 +21,21 @@ pub(crate) trait LazyInit {
|
||||
///
|
||||
/// It might be called more than once per LazyBox, as multiple threads
|
||||
/// might race to initialize it concurrently, each constructing and initializing
|
||||
/// their own box. (All but one of them will be destroyed right after.)
|
||||
/// their own box. All but one of them will be passed to `cancel_init` right after.
|
||||
fn init() -> Box<Self>;
|
||||
|
||||
/// Any surplus boxes from `init()` that lost the initialization race
|
||||
/// are passed to this function for disposal.
|
||||
///
|
||||
/// The default implementation calls destroy().
|
||||
fn cancel_init(x: Box<Self>) {
|
||||
Self::destroy(x);
|
||||
}
|
||||
|
||||
/// This is called to destroy a used box.
|
||||
///
|
||||
/// The default implementation just drops it.
|
||||
fn destroy(_: Box<Self>) {}
|
||||
}
|
||||
|
||||
impl<T: LazyInit> LazyBox<T> {
|
||||
@ -45,7 +58,7 @@ impl<T: LazyInit> LazyBox<T> {
|
||||
Err(ptr) => {
|
||||
// Lost the race to another thread.
|
||||
// Drop the box we created, and use the one from the other thread instead.
|
||||
drop(unsafe { Box::from_raw(new_ptr) });
|
||||
T::cancel_init(unsafe { Box::from_raw(new_ptr) });
|
||||
ptr
|
||||
}
|
||||
}
|
||||
@ -71,7 +84,7 @@ impl<T: LazyInit> Drop for LazyBox<T> {
|
||||
fn drop(&mut self) {
|
||||
let ptr = *self.ptr.get_mut();
|
||||
if !ptr.is_null() {
|
||||
drop(unsafe { Box::from_raw(ptr) });
|
||||
T::destroy(unsafe { Box::from_raw(ptr) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,10 @@
|
||||
# `--extern` Options
|
||||
|
||||
* Tracking issue for `--extern` crate modifiers: [#98405](https://github.com/rust-lang/rust/issues/98405)
|
||||
* Tracking issue for `noprelude`: [#98398](https://github.com/rust-lang/rust/issues/98398)
|
||||
* Tracking issue for `priv`: [#98399](https://github.com/rust-lang/rust/issues/98399)
|
||||
* Tracking issue for `nounused`: [#98400](https://github.com/rust-lang/rust/issues/98400)
|
||||
|
||||
The behavior of the `--extern` flag can be modified with `noprelude`, `priv` or `nounused` options.
|
||||
|
||||
This is unstable feature, so you have to provide `-Zunstable-options` to enable it.
|
||||
|
@ -2,7 +2,7 @@ error[E0599]: no variant or associated item named `mispellable` found for enum `
|
||||
--> $DIR/associated-item-enum.rs:17:11
|
||||
|
|
||||
LL | enum Enum { Variant }
|
||||
| --------- variant or associated item `mispellable` not found here
|
||||
| ---- variant or associated item `mispellable` not found for this enum
|
||||
...
|
||||
LL | Enum::mispellable();
|
||||
| ^^^^^^^^^^^
|
||||
@ -14,7 +14,7 @@ error[E0599]: no variant or associated item named `mispellable_trait` found for
|
||||
--> $DIR/associated-item-enum.rs:18:11
|
||||
|
|
||||
LL | enum Enum { Variant }
|
||||
| --------- variant or associated item `mispellable_trait` not found here
|
||||
| ---- variant or associated item `mispellable_trait` not found for this enum
|
||||
...
|
||||
LL | Enum::mispellable_trait();
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
@ -26,7 +26,7 @@ error[E0599]: no variant or associated item named `MISPELLABLE` found for enum `
|
||||
--> $DIR/associated-item-enum.rs:19:11
|
||||
|
|
||||
LL | enum Enum { Variant }
|
||||
| --------- variant or associated item `MISPELLABLE` not found here
|
||||
| ---- variant or associated item `MISPELLABLE` not found for this enum
|
||||
...
|
||||
LL | Enum::MISPELLABLE;
|
||||
| ^^^^^^^^^^^
|
||||
|
@ -2,7 +2,7 @@ error[E0599]: no method named `poll` found for struct `Sleep` in the current sco
|
||||
--> $DIR/pin-needed-to-poll.rs:42:20
|
||||
|
|
||||
LL | struct Sleep;
|
||||
| ------------- method `poll` not found for this
|
||||
| ----- method `poll` not found for this struct
|
||||
...
|
||||
LL | self.sleep.poll(cx)
|
||||
| ^^^^ method not found in `Sleep`
|
||||
|
@ -2,7 +2,7 @@ error[E0599]: no variant or associated item named `Hsl` found for enum `Color` i
|
||||
--> $DIR/bogus-tag.rs:7:16
|
||||
|
|
||||
LL | enum Color { Rgb(isize, isize, isize), Rgba(isize, isize, isize, isize), }
|
||||
| ---------- variant or associated item `Hsl` not found here
|
||||
| ----- variant or associated item `Hsl` not found for this enum
|
||||
...
|
||||
LL | Color::Hsl(h, s, l) => { println!("hsl"); }
|
||||
| ^^^ variant or associated item not found in `Color`
|
||||
|
@ -2,7 +2,7 @@ error[E0599]: no method named `closure` found for struct `Obj` in the current sc
|
||||
--> $DIR/issue-18343.rs:7:7
|
||||
|
|
||||
LL | struct Obj<F> where F: FnMut() -> u32 {
|
||||
| ------------------------------------- method `closure` not found for this
|
||||
| --- method `closure` not found for this struct
|
||||
...
|
||||
LL | o.closure();
|
||||
| ^^^^^^^ field, not a method
|
||||
|
@ -2,7 +2,7 @@ error[E0599]: no method named `closure` found for struct `Obj` in the current sc
|
||||
--> $DIR/issue-2392.rs:36:15
|
||||
|
|
||||
LL | struct Obj<F> where F: FnOnce() -> u32 {
|
||||
| -------------------------------------- method `closure` not found for this
|
||||
| --- method `closure` not found for this struct
|
||||
...
|
||||
LL | o_closure.closure();
|
||||
| ^^^^^^^ field, not a method
|
||||
@ -16,7 +16,7 @@ error[E0599]: no method named `not_closure` found for struct `Obj` in the curren
|
||||
--> $DIR/issue-2392.rs:38:15
|
||||
|
|
||||
LL | struct Obj<F> where F: FnOnce() -> u32 {
|
||||
| -------------------------------------- method `not_closure` not found for this
|
||||
| --- method `not_closure` not found for this struct
|
||||
...
|
||||
LL | o_closure.not_closure();
|
||||
| ^^^^^^^^^^^-- help: remove the arguments
|
||||
@ -27,7 +27,7 @@ error[E0599]: no method named `closure` found for struct `Obj` in the current sc
|
||||
--> $DIR/issue-2392.rs:42:12
|
||||
|
|
||||
LL | struct Obj<F> where F: FnOnce() -> u32 {
|
||||
| -------------------------------------- method `closure` not found for this
|
||||
| --- method `closure` not found for this struct
|
||||
...
|
||||
LL | o_func.closure();
|
||||
| ^^^^^^^ field, not a method
|
||||
@ -41,7 +41,7 @@ error[E0599]: no method named `boxed_closure` found for struct `BoxedObj` in the
|
||||
--> $DIR/issue-2392.rs:45:14
|
||||
|
|
||||
LL | struct BoxedObj {
|
||||
| --------------- method `boxed_closure` not found for this
|
||||
| -------- method `boxed_closure` not found for this struct
|
||||
...
|
||||
LL | boxed_fn.boxed_closure();
|
||||
| ^^^^^^^^^^^^^ field, not a method
|
||||
@ -55,7 +55,7 @@ error[E0599]: no method named `boxed_closure` found for struct `BoxedObj` in the
|
||||
--> $DIR/issue-2392.rs:48:19
|
||||
|
|
||||
LL | struct BoxedObj {
|
||||
| --------------- method `boxed_closure` not found for this
|
||||
| -------- method `boxed_closure` not found for this struct
|
||||
...
|
||||
LL | boxed_closure.boxed_closure();
|
||||
| ^^^^^^^^^^^^^ field, not a method
|
||||
@ -69,7 +69,7 @@ error[E0599]: no method named `closure` found for struct `Obj` in the current sc
|
||||
--> $DIR/issue-2392.rs:53:12
|
||||
|
|
||||
LL | struct Obj<F> where F: FnOnce() -> u32 {
|
||||
| -------------------------------------- method `closure` not found for this
|
||||
| --- method `closure` not found for this struct
|
||||
...
|
||||
LL | w.wrap.closure();
|
||||
| ^^^^^^^ field, not a method
|
||||
@ -83,7 +83,7 @@ error[E0599]: no method named `not_closure` found for struct `Obj` in the curren
|
||||
--> $DIR/issue-2392.rs:55:12
|
||||
|
|
||||
LL | struct Obj<F> where F: FnOnce() -> u32 {
|
||||
| -------------------------------------- method `not_closure` not found for this
|
||||
| --- method `not_closure` not found for this struct
|
||||
...
|
||||
LL | w.wrap.not_closure();
|
||||
| ^^^^^^^^^^^-- help: remove the arguments
|
||||
@ -94,7 +94,7 @@ error[E0599]: no method named `closure` found for struct `Obj` in the current sc
|
||||
--> $DIR/issue-2392.rs:58:24
|
||||
|
|
||||
LL | struct Obj<F> where F: FnOnce() -> u32 {
|
||||
| -------------------------------------- method `closure` not found for this
|
||||
| --- method `closure` not found for this struct
|
||||
...
|
||||
LL | check_expression().closure();
|
||||
| ^^^^^^^ field, not a method
|
||||
@ -108,7 +108,7 @@ error[E0599]: no method named `f1` found for struct `FuncContainer` in the curre
|
||||
--> $DIR/issue-2392.rs:64:31
|
||||
|
|
||||
LL | struct FuncContainer {
|
||||
| -------------------- method `f1` not found for this
|
||||
| ------------- method `f1` not found for this struct
|
||||
...
|
||||
LL | (*self.container).f1(1);
|
||||
| ^^ field, not a method
|
||||
@ -122,7 +122,7 @@ error[E0599]: no method named `f2` found for struct `FuncContainer` in the curre
|
||||
--> $DIR/issue-2392.rs:65:31
|
||||
|
|
||||
LL | struct FuncContainer {
|
||||
| -------------------- method `f2` not found for this
|
||||
| ------------- method `f2` not found for this struct
|
||||
...
|
||||
LL | (*self.container).f2(1);
|
||||
| ^^ field, not a method
|
||||
@ -136,7 +136,7 @@ error[E0599]: no method named `f3` found for struct `FuncContainer` in the curre
|
||||
--> $DIR/issue-2392.rs:66:31
|
||||
|
|
||||
LL | struct FuncContainer {
|
||||
| -------------------- method `f3` not found for this
|
||||
| ------------- method `f3` not found for this struct
|
||||
...
|
||||
LL | (*self.container).f3(1);
|
||||
| ^^ field, not a method
|
||||
|
@ -2,7 +2,7 @@ error[E0599]: no method named `example` found for struct `Example` in the curren
|
||||
--> $DIR/issue-32128.rs:12:10
|
||||
|
|
||||
LL | struct Example {
|
||||
| -------------- method `example` not found for this
|
||||
| ------- method `example` not found for this struct
|
||||
...
|
||||
LL | demo.example(1);
|
||||
| ^^^^^^^ field, not a method
|
||||
|
@ -2,7 +2,7 @@ error[E0599]: no method named `dog_age` found for struct `Dog` in the current sc
|
||||
--> $DIR/private-field.rs:16:23
|
||||
|
|
||||
LL | pub struct Dog {
|
||||
| -------------- method `dog_age` not found for this
|
||||
| --- method `dog_age` not found for this struct
|
||||
...
|
||||
LL | let dog_age = dog.dog_age();
|
||||
| ^^^^^^^ private field, not a method
|
||||
|
@ -8,7 +8,7 @@ error[E0599]: the function or associated item `foo` exists for struct `Foo<{_: u
|
||||
--> $DIR/issue-69654.rs:17:10
|
||||
|
|
||||
LL | struct Foo<const N: usize> {}
|
||||
| -------------------------- function or associated item `foo` not found for this
|
||||
| --- function or associated item `foo` not found for this struct
|
||||
...
|
||||
LL | Foo::foo();
|
||||
| ^^^ function or associated item cannot be called on `Foo<{_: usize}>` due to unsatisfied trait bounds
|
||||
|
@ -15,22 +15,16 @@ LL | [u8; size_of::<T>() + 1]: ,
|
||||
error[E0599]: the function or associated item `new` exists for struct `Inline<dyn Debug>`, but its trait bounds were not satisfied
|
||||
--> $DIR/issue-80742.rs:30:36
|
||||
|
|
||||
LL | / struct Inline<T>
|
||||
LL | | where
|
||||
LL | | [u8; size_of::<T>() + 1]: ,
|
||||
LL | | {
|
||||
LL | | _phantom: PhantomData<T>,
|
||||
LL | | buf: [u8; size_of::<T>() + 1],
|
||||
LL | | }
|
||||
| |_- function or associated item `new` not found for this
|
||||
LL | struct Inline<T>
|
||||
| ------ function or associated item `new` not found for this struct
|
||||
...
|
||||
LL | let dst = Inline::<dyn Debug>::new(0);
|
||||
| ^^^ function or associated item cannot be called on `Inline<dyn Debug>` due to unsatisfied trait bounds
|
||||
LL | let dst = Inline::<dyn Debug>::new(0);
|
||||
| ^^^ function or associated item cannot be called on `Inline<dyn Debug>` due to unsatisfied trait bounds
|
||||
|
|
||||
::: $SRC_DIR/core/src/fmt/mod.rs:LL:COL
|
||||
|
|
||||
LL | pub trait Debug {
|
||||
| --------------- doesn't satisfy `dyn Debug: Sized`
|
||||
LL | pub trait Debug {
|
||||
| --------------- doesn't satisfy `dyn Debug: Sized`
|
||||
|
|
||||
= note: the following trait bounds were not satisfied:
|
||||
`dyn Debug: Sized`
|
||||
|
@ -16,7 +16,7 @@ error[E0599]: no method named `f` found for struct `S` in the current scope
|
||||
--> $DIR/invalid-const-arg-for-type-param.rs:9:7
|
||||
|
|
||||
LL | struct S;
|
||||
| --------- method `f` not found for this
|
||||
| - method `f` not found for this struct
|
||||
...
|
||||
LL | S.f::<0>();
|
||||
| ^ method not found in `S`
|
||||
|
10
src/test/ui/const-generics/issues/issue-97634.rs
Normal file
10
src/test/ui/const-generics/issues/issue-97634.rs
Normal file
@ -0,0 +1,10 @@
|
||||
// build-pass
|
||||
|
||||
pub enum Register<const N: u16> {
|
||||
Field0 = 40,
|
||||
Field1,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _b = Register::<0>::Field1 as u16;
|
||||
}
|
@ -2,7 +2,7 @@ error[E0599]: no function or associated item named `assert` found for struct `Bo
|
||||
--> $DIR/const-needs_drop-monomorphic.rs:11:46
|
||||
|
|
||||
LL | struct Bool<const B: bool> {}
|
||||
| -------------------------- function or associated item `assert` not found for this
|
||||
| ---- function or associated item `assert` not found for this struct
|
||||
...
|
||||
LL | Bool::<{ std::mem::needs_drop::<T>() }>::assert();
|
||||
| ^^^^^^ function or associated item cannot be called on `Bool<{ std::mem::needs_drop::<T>() }>` due to unsatisfied trait bounds
|
||||
|
@ -2,7 +2,7 @@ error[E0599]: no method named `clone` found for struct `Foo` in the current scop
|
||||
--> $DIR/copy-a-resource.rs:18:16
|
||||
|
|
||||
LL | struct Foo {
|
||||
| ---------- method `clone` not found for this
|
||||
| --- method `clone` not found for this struct
|
||||
...
|
||||
LL | let _y = x.clone();
|
||||
| ^^^^^ method not found in `Foo`
|
||||
|
@ -3,8 +3,8 @@ error[E0599]: the method `clone` exists for struct `Bar<NotClone>`, but its trai
|
||||
|
|
||||
LL | struct Bar<T: Foo> {
|
||||
| ------------------
|
||||
| |
|
||||
| method `clone` not found for this
|
||||
| | |
|
||||
| | method `clone` not found for this struct
|
||||
| doesn't satisfy `Bar<NotClone>: Clone`
|
||||
...
|
||||
LL | struct NotClone;
|
||||
|
@ -37,7 +37,7 @@ LL | pub struct NoDerives;
|
||||
| --------------------- doesn't satisfy `NoDerives: Clone`
|
||||
...
|
||||
LL | struct Object<T, A>(T, A);
|
||||
| -------------------------- method `use_clone` not found for this
|
||||
| ------ method `use_clone` not found for this struct
|
||||
...
|
||||
LL | foo.use_clone();
|
||||
| ^^^^^^^^^ method cannot be called on `Object<NoDerives, SomeDerives>` due to unsatisfied trait bounds
|
||||
|
@ -25,7 +25,7 @@ LL | pub struct NoDerives;
|
||||
| --------------------- doesn't satisfy `NoDerives: Eq`
|
||||
LL |
|
||||
LL | struct Object<T>(T);
|
||||
| -------------------- method `use_eq` not found for this
|
||||
| ------ method `use_eq` not found for this struct
|
||||
...
|
||||
LL | foo.use_eq();
|
||||
| ^^^^^^ method cannot be called on `Object<NoDerives>` due to unsatisfied trait bounds
|
||||
@ -44,7 +44,7 @@ LL | pub struct NoDerives;
|
||||
| --------------------- doesn't satisfy `NoDerives: Ord`
|
||||
LL |
|
||||
LL | struct Object<T>(T);
|
||||
| -------------------- method `use_ord` not found for this
|
||||
| ------ method `use_ord` not found for this struct
|
||||
...
|
||||
LL | foo.use_ord();
|
||||
| ^^^^^^^ method cannot be called on `Object<NoDerives>` due to unsatisfied trait bounds
|
||||
@ -66,7 +66,7 @@ LL | pub struct NoDerives;
|
||||
| doesn't satisfy `NoDerives: PartialOrd`
|
||||
LL |
|
||||
LL | struct Object<T>(T);
|
||||
| -------------------- method `use_ord_and_partial_ord` not found for this
|
||||
| ------ method `use_ord_and_partial_ord` not found for this struct
|
||||
...
|
||||
LL | foo.use_ord_and_partial_ord();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ method cannot be called on `Object<NoDerives>` due to unsatisfied trait bounds
|
||||
|
@ -88,7 +88,7 @@ error[E0599]: no method named `hello_method` found for struct `S` in the current
|
||||
--> $DIR/issue-40006.rs:38:7
|
||||
|
|
||||
LL | struct S;
|
||||
| --------- method `hello_method` not found for this
|
||||
| - method `hello_method` not found for this struct
|
||||
...
|
||||
LL | S.hello_method();
|
||||
| ^^^^^^^^^^^^ method not found in `S`
|
||||
|
@ -2,7 +2,7 @@ error[E0599]: no function or associated item named `new` found for struct `T` in
|
||||
--> $DIR/dont-suggest-private-trait-method.rs:4:8
|
||||
|
|
||||
LL | struct T;
|
||||
| --------- function or associated item `new` not found for this
|
||||
| - function or associated item `new` not found for this struct
|
||||
...
|
||||
LL | T::new();
|
||||
| ^^^ function or associated item not found in `T`
|
||||
|
@ -2,7 +2,7 @@ error[E0599]: no associated item named `NotEvenReal` found for struct `Foo` in t
|
||||
--> $DIR/E0599.rs:4:20
|
||||
|
|
||||
LL | struct Foo;
|
||||
| ----------- associated item `NotEvenReal` not found for this
|
||||
| --- associated item `NotEvenReal` not found for this struct
|
||||
...
|
||||
LL | || if let Foo::NotEvenReal() = Foo {};
|
||||
| ^^^^^^^^^^^ associated item not found in `Foo`
|
||||
|
@ -3,8 +3,8 @@ error[E0599]: the method `f` exists for struct `S`, but its trait bounds were no
|
||||
|
|
||||
LL | struct S;
|
||||
| ---------
|
||||
| |
|
||||
| method `f` not found for this
|
||||
| | |
|
||||
| | method `f` not found for this struct
|
||||
| doesn't satisfy `<S as X>::Y<i32> = i32`
|
||||
| doesn't satisfy `S: M`
|
||||
...
|
||||
|
@ -3,8 +3,8 @@ error[E0599]: the method `filterx` exists for struct `Map<Repeat, [closure@$DIR/
|
||||
|
|
||||
LL | pub struct Map<S, F> {
|
||||
| --------------------
|
||||
| |
|
||||
| method `filterx` not found for this
|
||||
| | |
|
||||
| | method `filterx` not found for this struct
|
||||
| doesn't satisfy `_: StreamExt`
|
||||
...
|
||||
LL | let filter = map.filterx(|x: &_| true);
|
||||
@ -28,8 +28,8 @@ error[E0599]: the method `countx` exists for struct `Filter<Map<Repeat, for<'r>
|
||||
|
|
||||
LL | pub struct Filter<S, F> {
|
||||
| -----------------------
|
||||
| |
|
||||
| method `countx` not found for this
|
||||
| | |
|
||||
| | method `countx` not found for this struct
|
||||
| doesn't satisfy `_: StreamExt`
|
||||
...
|
||||
LL | let count = filter.countx();
|
||||
|
@ -2,7 +2,7 @@ error[E0599]: no method named `foo` found for struct `Bar` in the current scope
|
||||
--> $DIR/issue-21659-show-relevant-trait-impls-3.rs:20:8
|
||||
|
|
||||
LL | struct Bar;
|
||||
| ----------- method `foo` not found for this
|
||||
| --- method `foo` not found for this struct
|
||||
...
|
||||
LL | f1.foo(1usize);
|
||||
| ^^^ method not found in `Bar`
|
||||
|
@ -21,7 +21,7 @@ LL | pub struct RawImpl<T>(PhantomData<T>);
|
||||
| -------------------------------------- doesn't satisfy `RawImpl<()>: Raw<()>`
|
||||
...
|
||||
LL | pub struct SafeImpl<T: ?Sized, A: Raw<T>>(PhantomData<(A, T)>);
|
||||
| --------------------------------------------------------------- function or associated item `foo` not found for this
|
||||
| -------- function or associated item `foo` not found for this struct
|
||||
|
|
||||
= note: the following trait bounds were not satisfied:
|
||||
`RawImpl<()>: Raw<()>`
|
||||
|
@ -2,7 +2,7 @@ error[E0599]: no method named `is_empty` found for struct `Foo` in the current s
|
||||
--> $DIR/method-suggestion-no-duplication.rs:7:15
|
||||
|
|
||||
LL | struct Foo;
|
||||
| ----------- method `is_empty` not found for this
|
||||
| --- method `is_empty` not found for this struct
|
||||
...
|
||||
LL | foo(|s| s.is_empty());
|
||||
| ^^^^^^^^ method not found in `Foo`
|
||||
|
@ -94,7 +94,7 @@ error[E0599]: no method named `method` found for struct `Foo` in the current sco
|
||||
--> $DIR/no-method-suggested-traits.rs:40:9
|
||||
|
|
||||
LL | struct Foo;
|
||||
| ----------- method `method` not found for this
|
||||
| --- method `method` not found for this struct
|
||||
...
|
||||
LL | Foo.method();
|
||||
| ^^^^^^ method not found in `Foo`
|
||||
@ -201,7 +201,7 @@ error[E0599]: no method named `method3` found for struct `Foo` in the current sc
|
||||
--> $DIR/no-method-suggested-traits.rs:59:9
|
||||
|
|
||||
LL | struct Foo;
|
||||
| ----------- method `method3` not found for this
|
||||
| --- method `method3` not found for this struct
|
||||
...
|
||||
LL | Foo.method3();
|
||||
| ^^^^^^^ method not found in `Foo`
|
||||
@ -224,7 +224,7 @@ error[E0599]: no method named `method3` found for enum `Bar` in the current scop
|
||||
--> $DIR/no-method-suggested-traits.rs:63:12
|
||||
|
|
||||
LL | enum Bar { X }
|
||||
| -------- method `method3` not found for this
|
||||
| --- method `method3` not found for this enum
|
||||
...
|
||||
LL | Bar::X.method3();
|
||||
| ^^^^^^^ method not found in `Bar`
|
||||
|
@ -43,7 +43,7 @@ error[E0599]: no method named `bar` found for struct `Foo` in the current scope
|
||||
--> $DIR/infinite-autoderef.rs:25:9
|
||||
|
|
||||
LL | struct Foo;
|
||||
| ----------- method `bar` not found for this
|
||||
| --- method `bar` not found for this struct
|
||||
...
|
||||
LL | Foo.bar();
|
||||
| ^^^ method not found in `Foo`
|
||||
|
@ -2,7 +2,7 @@ error[E0599]: no method named `kaname` found for struct `Homura` in the current
|
||||
--> $DIR/issue-19692.rs:4:40
|
||||
|
|
||||
LL | struct Homura;
|
||||
| -------------- method `kaname` not found for this
|
||||
| ------ method `kaname` not found for this struct
|
||||
...
|
||||
LL | let Some(ref madoka) = Some(homura.kaname());
|
||||
| ^^^^^^ method not found in `Homura`
|
||||
|
@ -2,7 +2,7 @@ error[E0599]: no variant or associated item named `PIE` found for enum `Deliciou
|
||||
--> $DIR/issue-22933-2.rs:4:55
|
||||
|
|
||||
LL | enum Delicious {
|
||||
| -------------- variant or associated item `PIE` not found here
|
||||
| --------- variant or associated item `PIE` not found for this enum
|
||||
...
|
||||
LL | ApplePie = Delicious::Apple as isize | Delicious::PIE as isize,
|
||||
| ^^^
|
||||
|
@ -2,7 +2,7 @@ error[E0599]: no variant or associated item named `Homura` found for enum `Token
|
||||
--> $DIR/issue-23173.rs:9:23
|
||||
|
|
||||
LL | enum Token { LeftParen, RightParen, Plus, Minus, /* etc */ }
|
||||
| ---------- variant or associated item `Homura` not found here
|
||||
| ----- variant or associated item `Homura` not found for this enum
|
||||
...
|
||||
LL | use_token(&Token::Homura);
|
||||
| ^^^^^^ variant or associated item not found in `Token`
|
||||
@ -11,7 +11,7 @@ error[E0599]: no function or associated item named `method` found for struct `St
|
||||
--> $DIR/issue-23173.rs:10:13
|
||||
|
|
||||
LL | struct Struct {
|
||||
| ------------- function or associated item `method` not found for this
|
||||
| ------ function or associated item `method` not found for this struct
|
||||
...
|
||||
LL | Struct::method();
|
||||
| ^^^^^^ function or associated item not found in `Struct`
|
||||
@ -20,7 +20,7 @@ error[E0599]: no function or associated item named `method` found for struct `St
|
||||
--> $DIR/issue-23173.rs:11:13
|
||||
|
|
||||
LL | struct Struct {
|
||||
| ------------- function or associated item `method` not found for this
|
||||
| ------ function or associated item `method` not found for this struct
|
||||
...
|
||||
LL | Struct::method;
|
||||
| ^^^^^^ function or associated item not found in `Struct`
|
||||
@ -29,7 +29,7 @@ error[E0599]: no associated item named `Assoc` found for struct `Struct` in the
|
||||
--> $DIR/issue-23173.rs:12:13
|
||||
|
|
||||
LL | struct Struct {
|
||||
| ------------- associated item `Assoc` not found for this
|
||||
| ------ associated item `Assoc` not found for this struct
|
||||
...
|
||||
LL | Struct::Assoc;
|
||||
| ^^^^^ associated item not found in `Struct`
|
||||
|
@ -2,7 +2,7 @@ error[E0599]: no variant or associated item named `A` found for enum `SomeEnum`
|
||||
--> $DIR/issue-23217.rs:2:19
|
||||
|
|
||||
LL | pub enum SomeEnum {
|
||||
| ----------------- variant or associated item `A` not found here
|
||||
| -------- variant or associated item `A` not found for this enum
|
||||
LL | B = SomeEnum::A,
|
||||
| ^
|
||||
| |
|
||||
|
@ -2,7 +2,7 @@ error[E0599]: no method named `clone` found for struct `C` in the current scope
|
||||
--> $DIR/issue-2823.rs:13:16
|
||||
|
|
||||
LL | struct C {
|
||||
| -------- method `clone` not found for this
|
||||
| - method `clone` not found for this struct
|
||||
...
|
||||
LL | let _d = c.clone();
|
||||
| ^^^^^ method not found in `C`
|
||||
|
@ -2,7 +2,7 @@ error[E0599]: no variant or associated item named `Baz` found for enum `Foo` in
|
||||
--> $DIR/issue-28971.rs:7:18
|
||||
|
|
||||
LL | enum Foo {
|
||||
| -------- variant or associated item `Baz` not found here
|
||||
| --- variant or associated item `Baz` not found for this enum
|
||||
...
|
||||
LL | Foo::Baz(..) => (),
|
||||
| ^^^
|
||||
|
@ -1,6 +1,8 @@
|
||||
error[E0599]: no associated item named `Item` found for type parameter `T` in the current scope
|
||||
--> $DIR/issue-38919.rs:2:8
|
||||
|
|
||||
LL | fn foo<T: Iterator>() {
|
||||
| - associated item `Item` not found for this type parameter
|
||||
LL | T::Item;
|
||||
| ^^^^ associated item not found in `T`
|
||||
|
||||
|
@ -2,7 +2,7 @@ error[E0599]: no method named `iter` found for struct `Iterate` in the current s
|
||||
--> $DIR/issue-41880.rs:27:24
|
||||
|
|
||||
LL | pub struct Iterate<T, F> {
|
||||
| ------------------------ method `iter` not found for this
|
||||
| ------- method `iter` not found for this struct
|
||||
...
|
||||
LL | println!("{:?}", a.iter().take(10).collect::<Vec<usize>>());
|
||||
| ^^^^ method not found in `Iterate<{integer}, [closure@$DIR/issue-41880.rs:26:24: 26:31]>`
|
||||
|
@ -2,7 +2,7 @@ error[E0599]: no method named `bar` found for struct `Foo` in the current scope
|
||||
--> $DIR/issue-64430.rs:7:9
|
||||
|
|
||||
LL | pub struct Foo;
|
||||
| --------------- method `bar` not found for this
|
||||
| --- method `bar` not found for this struct
|
||||
...
|
||||
LL | Foo.bar()
|
||||
| ^^^ method not found in `Foo`
|
||||
|
@ -2,7 +2,7 @@ error[E0599]: no function or associated item named `bar` found for struct `Foo`
|
||||
--> $DIR/issue-7950.rs:6:10
|
||||
|
|
||||
LL | struct Foo;
|
||||
| ----------- function or associated item `bar` not found for this
|
||||
| --- function or associated item `bar` not found for this struct
|
||||
...
|
||||
LL | Foo::bar();
|
||||
| ^^^ function or associated item not found in `Foo`
|
||||
|
@ -7,6 +7,8 @@ LL | let t = T { i: 0 };
|
||||
error[E0599]: no function or associated item named `f` found for type parameter `Foo` in the current scope
|
||||
--> $DIR/lexical-scopes.rs:10:10
|
||||
|
|
||||
LL | fn g<Foo>() {
|
||||
| --- function or associated item `f` not found for this type parameter
|
||||
LL | Foo::f();
|
||||
| ^ function or associated item not found in `Foo`
|
||||
|
||||
|
@ -51,8 +51,8 @@ error[E0599]: `Foo` is not an iterator
|
||||
|
|
||||
LL | pub struct Foo;
|
||||
| ---------------
|
||||
| |
|
||||
| method `take` not found for this
|
||||
| | |
|
||||
| | method `take` not found for this struct
|
||||
| doesn't satisfy `Foo: Iterator`
|
||||
...
|
||||
LL | .take()
|
||||
|
@ -2,7 +2,7 @@ error[E0599]: no method named `distance` found for struct `Point<i32>` in the cu
|
||||
--> $DIR/method-not-found-generic-arg-elision.rs:82:23
|
||||
|
|
||||
LL | struct Point<T> {
|
||||
| --------------- method `distance` not found for this
|
||||
| ----- method `distance` not found for this struct
|
||||
...
|
||||
LL | let d = point_i32.distance();
|
||||
| ^^^^^^^^ method not found in `Point<i32>`
|
||||
@ -14,7 +14,7 @@ error[E0599]: no method named `other` found for struct `Point` in the current sc
|
||||
--> $DIR/method-not-found-generic-arg-elision.rs:84:23
|
||||
|
|
||||
LL | struct Point<T> {
|
||||
| --------------- method `other` not found for this
|
||||
| ----- method `other` not found for this struct
|
||||
...
|
||||
LL | let d = point_i32.other();
|
||||
| ^^^^^ method not found in `Point<i32>`
|
||||
@ -29,7 +29,7 @@ error[E0599]: no method named `method` found for struct `Wrapper<bool>` in the c
|
||||
--> $DIR/method-not-found-generic-arg-elision.rs:90:13
|
||||
|
|
||||
LL | struct Wrapper<T>(T);
|
||||
| --------------------- method `method` not found for this
|
||||
| ------- method `method` not found for this struct
|
||||
...
|
||||
LL | wrapper.method();
|
||||
| ^^^^^^ method not found in `Wrapper<bool>`
|
||||
@ -45,7 +45,7 @@ error[E0599]: no method named `other` found for struct `Wrapper` in the current
|
||||
--> $DIR/method-not-found-generic-arg-elision.rs:92:13
|
||||
|
|
||||
LL | struct Wrapper<T>(T);
|
||||
| --------------------- method `other` not found for this
|
||||
| ------- method `other` not found for this struct
|
||||
...
|
||||
LL | wrapper.other();
|
||||
| ^^^^^ method not found in `Wrapper<bool>`
|
||||
@ -54,7 +54,7 @@ error[E0599]: no method named `method` found for struct `Wrapper2<'_, bool, 3_us
|
||||
--> $DIR/method-not-found-generic-arg-elision.rs:96:13
|
||||
|
|
||||
LL | struct Wrapper2<'a, T, const C: usize> {
|
||||
| -------------------------------------- method `method` not found for this
|
||||
| -------- method `method` not found for this struct
|
||||
...
|
||||
LL | wrapper.method();
|
||||
| ^^^^^^ method not found in `Wrapper2<'_, bool, 3_usize>`
|
||||
@ -68,7 +68,7 @@ error[E0599]: no method named `other` found for struct `Wrapper2` in the current
|
||||
--> $DIR/method-not-found-generic-arg-elision.rs:98:13
|
||||
|
|
||||
LL | struct Wrapper2<'a, T, const C: usize> {
|
||||
| -------------------------------------- method `other` not found for this
|
||||
| -------- method `other` not found for this struct
|
||||
...
|
||||
LL | wrapper.other();
|
||||
| ^^^^^ method not found in `Wrapper2<'_, bool, 3_usize>`
|
||||
@ -83,7 +83,7 @@ error[E0599]: the method `method` exists for struct `Struct<f64>`, but its trait
|
||||
--> $DIR/method-not-found-generic-arg-elision.rs:104:7
|
||||
|
|
||||
LL | struct Struct<T>{
|
||||
| ---------------- method `method` not found for this
|
||||
| ------ method `method` not found for this struct
|
||||
...
|
||||
LL | s.method();
|
||||
| ^^^^^^ method cannot be called on `Struct<f64>` due to unsatisfied trait bounds
|
||||
|
@ -21,4 +21,17 @@ fn main() {
|
||||
let _ = |&mut _a: &mut u32| (); //~ ERROR mismatched types
|
||||
let _ = |&_a: &u32| (); //~ ERROR mismatched types
|
||||
let _ = |&mut _a: &mut u32| (); //~ ERROR mismatched types
|
||||
|
||||
#[allow(unused_mut)]
|
||||
{
|
||||
struct S(u8);
|
||||
|
||||
let mut _a = 0; //~ ERROR mismatched types
|
||||
let S(_b) = S(0); //~ ERROR mismatched types
|
||||
let (_c,) = (0,); //~ ERROR mismatched types
|
||||
|
||||
match 0 {
|
||||
_d => {} //~ ERROR mismatched types
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,4 +21,17 @@ fn main() {
|
||||
let _ = |&mut &_a: &mut u32| (); //~ ERROR mismatched types
|
||||
let _ = |&&mut _a: &u32| (); //~ ERROR mismatched types
|
||||
let _ = |&mut &mut _a: &mut u32| (); //~ ERROR mismatched types
|
||||
|
||||
#[allow(unused_mut)]
|
||||
{
|
||||
struct S(u8);
|
||||
|
||||
let &mut _a = 0; //~ ERROR mismatched types
|
||||
let S(&mut _b) = S(0); //~ ERROR mismatched types
|
||||
let (&mut _c,) = (0,); //~ ERROR mismatched types
|
||||
|
||||
match 0 {
|
||||
&mut _d => {} //~ ERROR mismatched types
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,11 @@ LL | fn _f1(&mut _a: u32) {}
|
||||
|
|
||||
= note: expected type `u32`
|
||||
found mutable reference `&mut _`
|
||||
note: to declare a mutable parameter use: `mut _a`
|
||||
--> $DIR/ref-pat-suggestions.rs:4:8
|
||||
|
|
||||
LL | fn _f1(&mut _a: u32) {}
|
||||
| ^^^^^^^
|
||||
help: to take parameter `_a` by reference, move `&mut` to the type
|
||||
|
|
||||
LL - fn _f1(&mut _a: u32) {}
|
||||
@ -122,6 +127,11 @@ LL | let _: fn(u32) = |&mut _a| ();
|
||||
|
|
||||
= note: expected type `u32`
|
||||
found mutable reference `&mut _`
|
||||
note: to declare a mutable parameter use: `mut _a`
|
||||
--> $DIR/ref-pat-suggestions.rs:12:23
|
||||
|
|
||||
LL | let _: fn(u32) = |&mut _a| ();
|
||||
| ^^^^^^^
|
||||
help: consider removing `&mut` from the pattern
|
||||
|
|
||||
LL - let _: fn(u32) = |&mut _a| ();
|
||||
@ -222,6 +232,11 @@ LL | let _ = |&mut _a: u32| ();
|
||||
|
|
||||
= note: expected type `u32`
|
||||
found mutable reference `&mut _`
|
||||
note: to declare a mutable parameter use: `mut _a`
|
||||
--> $DIR/ref-pat-suggestions.rs:19:14
|
||||
|
|
||||
LL | let _ = |&mut _a: u32| ();
|
||||
| ^^^^^^^
|
||||
help: to take parameter `_a` by reference, move `&mut` to the type
|
||||
|
|
||||
LL - let _ = |&mut _a: u32| ();
|
||||
@ -292,6 +307,81 @@ LL - let _ = |&mut &mut _a: &mut u32| ();
|
||||
LL + let _ = |&mut _a: &mut u32| ();
|
||||
|
|
||||
|
||||
error: aborting due to 18 previous errors
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/ref-pat-suggestions.rs:29:13
|
||||
|
|
||||
LL | let &mut _a = 0;
|
||||
| ^^^^^^^ - this expression has type `{integer}`
|
||||
| |
|
||||
| expected integer, found `&mut _`
|
||||
| help: to declare a mutable variable use: `mut _a`
|
||||
|
|
||||
= note: expected type `{integer}`
|
||||
found mutable reference `&mut _`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/ref-pat-suggestions.rs:30:15
|
||||
|
|
||||
LL | let S(&mut _b) = S(0);
|
||||
| ^^^^^^^ ---- this expression has type `S`
|
||||
| |
|
||||
| expected `u8`, found `&mut _`
|
||||
|
|
||||
= note: expected type `u8`
|
||||
found mutable reference `&mut _`
|
||||
note: to declare a mutable binding use: `mut _b`
|
||||
--> $DIR/ref-pat-suggestions.rs:30:15
|
||||
|
|
||||
LL | let S(&mut _b) = S(0);
|
||||
| ^^^^^^^
|
||||
help: consider removing `&mut` from the pattern
|
||||
|
|
||||
LL - let S(&mut _b) = S(0);
|
||||
LL + let S(_b) = S(0);
|
||||
|
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/ref-pat-suggestions.rs:31:14
|
||||
|
|
||||
LL | let (&mut _c,) = (0,);
|
||||
| ^^^^^^^ ---- this expression has type `({integer},)`
|
||||
| |
|
||||
| expected integer, found `&mut _`
|
||||
|
|
||||
= note: expected type `{integer}`
|
||||
found mutable reference `&mut _`
|
||||
note: to declare a mutable binding use: `mut _c`
|
||||
--> $DIR/ref-pat-suggestions.rs:31:14
|
||||
|
|
||||
LL | let (&mut _c,) = (0,);
|
||||
| ^^^^^^^
|
||||
help: consider removing `&mut` from the pattern
|
||||
|
|
||||
LL - let (&mut _c,) = (0,);
|
||||
LL + let (_c,) = (0,);
|
||||
|
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/ref-pat-suggestions.rs:34:13
|
||||
|
|
||||
LL | match 0 {
|
||||
| - this expression has type `{integer}`
|
||||
LL | &mut _d => {}
|
||||
| ^^^^^^^ expected integer, found `&mut _`
|
||||
|
|
||||
= note: expected type `{integer}`
|
||||
found mutable reference `&mut _`
|
||||
note: to declare a mutable binding use: `mut _d`
|
||||
--> $DIR/ref-pat-suggestions.rs:34:13
|
||||
|
|
||||
LL | &mut _d => {}
|
||||
| ^^^^^^^
|
||||
help: consider removing `&mut` from the pattern
|
||||
|
|
||||
LL - &mut _d => {}
|
||||
LL + _d => {}
|
||||
|
|
||||
|
||||
error: aborting due to 22 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
@ -2,7 +2,7 @@ error[E0599]: no method named `clone` found for struct `Foo` in the current scop
|
||||
--> $DIR/noncopyable-class.rs:34:16
|
||||
|
|
||||
LL | struct Foo {
|
||||
| ---------- method `clone` not found for this
|
||||
| --- method `clone` not found for this struct
|
||||
...
|
||||
LL | let _y = x.clone();
|
||||
| ^^^^^ method not found in `Foo`
|
||||
|
@ -77,7 +77,7 @@ error[E0599]: no function or associated item named `full_of✨` found for struct
|
||||
--> $DIR/emoji-identifiers.rs:9:8
|
||||
|
|
||||
LL | struct 👀;
|
||||
| ---------- function or associated item `full_of✨` not found for this
|
||||
| -- function or associated item `full_of✨` not found for this struct
|
||||
...
|
||||
LL | 👀::full_of✨()
|
||||
| ^^^^^^^^^
|
||||
|
@ -8,6 +8,11 @@ LL | for ((_, _), (&mut c, _)) in &mut map {
|
||||
|
|
||||
= note: expected type `char`
|
||||
found mutable reference `&mut _`
|
||||
note: to declare a mutable binding use: `mut c`
|
||||
--> $DIR/for-loop-bad-item.rs:7:19
|
||||
|
|
||||
LL | for ((_, _), (&mut c, _)) in &mut map {
|
||||
| ^^^^^^
|
||||
help: consider removing `&mut` from the pattern
|
||||
|
|
||||
LL - for ((_, _), (&mut c, _)) in &mut map {
|
||||
|
@ -2,7 +2,7 @@ error[E0599]: no function or associated item named `deserialize` found for struc
|
||||
--> $DIR/issue-87932.rs:13:8
|
||||
|
|
||||
LL | pub struct A {}
|
||||
| ------------ function or associated item `deserialize` not found for this
|
||||
| - function or associated item `deserialize` not found for this struct
|
||||
...
|
||||
LL | A::deserialize();
|
||||
| ^^^^^^^^^^^ function or associated item not found in `A`
|
||||
|
@ -2,7 +2,7 @@ error[E0599]: no method named `foo` found for struct `A` in the current scope
|
||||
--> $DIR/point-at-arbitrary-self-type-method.rs:8:7
|
||||
|
|
||||
LL | struct A;
|
||||
| --------- method `foo` not found for this
|
||||
| - method `foo` not found for this struct
|
||||
...
|
||||
LL | fn foo(self: Box<Self>) {}
|
||||
| --- the method is available for `Box<A>` here
|
||||
|
@ -6,7 +6,7 @@ LL | trait B { fn foo(self: Box<Self>); }
|
||||
| |
|
||||
| the method is available for `Box<A>` here
|
||||
LL | struct A;
|
||||
| --------- method `foo` not found for this
|
||||
| - method `foo` not found for this struct
|
||||
...
|
||||
LL | A.foo()
|
||||
| ^^^ method not found in `A`
|
||||
|
@ -42,7 +42,7 @@ error[E0599]: no method named `fff` found for struct `Myisize` in the current sc
|
||||
--> $DIR/issue-7575.rs:62:30
|
||||
|
|
||||
LL | struct Myisize(isize);
|
||||
| ---------------------- method `fff` not found for this
|
||||
| ------- method `fff` not found for this struct
|
||||
...
|
||||
LL | u.f8(42) + u.f9(342) + m.fff(42)
|
||||
| --^^^
|
||||
@ -60,6 +60,8 @@ LL | fn fff(i: isize) -> isize {
|
||||
error[E0599]: no method named `is_str` found for type parameter `T` in the current scope
|
||||
--> $DIR/issue-7575.rs:70:7
|
||||
|
|
||||
LL | fn param_bound<T: ManyImplTrait>(t: T) -> bool {
|
||||
| - method `is_str` not found for this type parameter
|
||||
LL | t.is_str()
|
||||
| ^^^^^^ this is an associated function, not a method
|
||||
|
|
||||
|
@ -13,8 +13,8 @@ error[E0599]: the method `foo_one` exists for struct `MyStruct`, but its trait b
|
||||
|
|
||||
LL | struct MyStruct;
|
||||
| ----------------
|
||||
| |
|
||||
| method `foo_one` not found for this
|
||||
| | |
|
||||
| | method `foo_one` not found for this struct
|
||||
| doesn't satisfy `MyStruct: Foo`
|
||||
...
|
||||
LL | println!("{}", MyStruct.foo_one());
|
||||
|
@ -11,7 +11,7 @@ LL | enum CloneEnum {
|
||||
| -------------- doesn't satisfy `CloneEnum: Default`
|
||||
...
|
||||
LL | struct Foo<X, Y> (X, Y);
|
||||
| ------------------------ method `test` not found for this
|
||||
| --- method `test` not found for this struct
|
||||
...
|
||||
LL | let y = x.test();
|
||||
| ^^^^ method cannot be called on `Foo<Enum, CloneEnum>` due to unsatisfied trait bounds
|
||||
@ -49,7 +49,7 @@ LL | struct CloneStruct {
|
||||
| ------------------ doesn't satisfy `CloneStruct: Default`
|
||||
...
|
||||
LL | struct Foo<X, Y> (X, Y);
|
||||
| ------------------------ method `test` not found for this
|
||||
| --- method `test` not found for this struct
|
||||
...
|
||||
LL | let y = x.test();
|
||||
| ^^^^ method cannot be called on `Foo<Struct, CloneStruct>` due to unsatisfied trait bounds
|
||||
@ -71,7 +71,7 @@ error[E0599]: the method `test` exists for struct `Foo<Vec<Enum>, Instant>`, but
|
||||
--> $DIR/derive-trait-for-method-call.rs:40:15
|
||||
|
|
||||
LL | struct Foo<X, Y> (X, Y);
|
||||
| ------------------------ method `test` not found for this
|
||||
| --- method `test` not found for this struct
|
||||
...
|
||||
LL | let y = x.test();
|
||||
| ^^^^ method cannot be called on `Foo<Vec<Enum>, Instant>` due to unsatisfied trait bounds
|
||||
|
@ -2,7 +2,7 @@ error[E0599]: no method named `pick` found for struct `Chaenomeles` in the curre
|
||||
--> $DIR/dont-wrap-ambiguous-receivers.rs:18:25
|
||||
|
|
||||
LL | pub struct Chaenomeles;
|
||||
| ----------------------- method `pick` not found for this
|
||||
| ----------- method `pick` not found for this struct
|
||||
...
|
||||
LL | banana::Chaenomeles.pick()
|
||||
| ^^^^ method not found in `Chaenomeles`
|
||||
|
@ -2,7 +2,7 @@ error[E0599]: no method named `kind` found for struct `InferOk` in the current s
|
||||
--> $DIR/field-has-method.rs:19:15
|
||||
|
|
||||
LL | struct InferOk<T> {
|
||||
| ----------------- method `kind` not found for this
|
||||
| ------- method `kind` not found for this struct
|
||||
...
|
||||
LL | let k = i.kind();
|
||||
| ^^^^ method not found in `InferOk<Ty>`
|
||||
|
@ -1,6 +1,8 @@
|
||||
error[E0599]: no method named `hello` found for type parameter `impl Foo` in the current scope
|
||||
--> $DIR/impl-trait-with-missing-trait-bounds-in-arg.rs:15:9
|
||||
|
|
||||
LL | fn test(foo: impl Foo) {
|
||||
| -------- method `hello` not found for this type parameter
|
||||
LL | foo.hello();
|
||||
| ^^^^^ method not found in `impl Foo`
|
||||
|
|
||||
|
@ -13,6 +13,8 @@ LL | fn call_method<T: std::fmt::Debug + Foo>(x: &T) {
|
||||
error[E0599]: no method named `method` found for type parameter `T` in the current scope
|
||||
--> $DIR/issue-21673.rs:10:7
|
||||
|
|
||||
LL | fn call_method_2<T>(x: T) {
|
||||
| - method `method` not found for this type parameter
|
||||
LL | x.method()
|
||||
| ^^^^^^ method not found in `T`
|
||||
|
|
||||
|
@ -2,7 +2,7 @@ error[E0599]: no method named `default_hello` found for struct `GenericAssocMeth
|
||||
--> $DIR/suggest-assoc-fn-call-with-turbofish.rs:9:7
|
||||
|
|
||||
LL | struct GenericAssocMethod<T>(T);
|
||||
| -------------------------------- method `default_hello` not found for this
|
||||
| ------------------ method `default_hello` not found for this struct
|
||||
...
|
||||
LL | x.default_hello();
|
||||
| --^^^^^^^^^^^^^
|
||||
|
@ -2,7 +2,7 @@ error[E0599]: no method named `bat` found for struct `Foo` in the current scope
|
||||
--> $DIR/suggest-methods.rs:18:7
|
||||
|
|
||||
LL | struct Foo;
|
||||
| ----------- method `bat` not found for this
|
||||
| --- method `bat` not found for this struct
|
||||
...
|
||||
LL | f.bat(1.0);
|
||||
| ^^^ help: there is an associated function with a similar name: `bar`
|
||||
|
@ -29,7 +29,7 @@ error[E0599]: no variant or associated item named `Squareee` found for enum `Sha
|
||||
--> $DIR/suggest-variants.rs:15:12
|
||||
|
|
||||
LL | enum Shape {
|
||||
| ---------- variant or associated item `Squareee` not found here
|
||||
| ----- variant or associated item `Squareee` not found for this enum
|
||||
...
|
||||
LL | Shape::Squareee;
|
||||
| ^^^^^^^^
|
||||
@ -41,7 +41,7 @@ error[E0599]: no variant or associated item named `Circl` found for enum `Shape`
|
||||
--> $DIR/suggest-variants.rs:16:12
|
||||
|
|
||||
LL | enum Shape {
|
||||
| ---------- variant or associated item `Circl` not found here
|
||||
| ----- variant or associated item `Circl` not found for this enum
|
||||
...
|
||||
LL | Shape::Circl;
|
||||
| ^^^^^
|
||||
@ -53,7 +53,7 @@ error[E0599]: no variant or associated item named `Rombus` found for enum `Shape
|
||||
--> $DIR/suggest-variants.rs:17:12
|
||||
|
|
||||
LL | enum Shape {
|
||||
| ---------- variant or associated item `Rombus` not found here
|
||||
| ----- variant or associated item `Rombus` not found for this enum
|
||||
...
|
||||
LL | Shape::Rombus;
|
||||
| ^^^^^^ variant or associated item not found in `Shape`
|
||||
|
@ -8,7 +8,7 @@ LL | fn abc(&self) {}
|
||||
| --- the method is available for `S` here
|
||||
LL | }
|
||||
LL | pub struct S;
|
||||
| ------------- method `abc` not found for this
|
||||
| - method `abc` not found for this struct
|
||||
|
|
||||
= help: items from traits can only be used if the trait is in scope
|
||||
help: the following trait is implemented but not in scope; perhaps add a `use` for it:
|
||||
|
@ -11,7 +11,7 @@ error[E0599]: no function or associated item named `new` found for struct `Point
|
||||
--> $DIR/issue-3973.rs:22:20
|
||||
|
|
||||
LL | struct Point {
|
||||
| ------------ function or associated item `new` not found for this
|
||||
| ----- function or associated item `new` not found for this struct
|
||||
...
|
||||
LL | let p = Point::new(0.0, 0.0);
|
||||
| ^^^ function or associated item not found in `Point`
|
||||
|
@ -1,6 +1,8 @@
|
||||
error[E0599]: no method named `foo` found for type parameter `T` in the current scope
|
||||
--> $DIR/issue-65284-suggest-generic-trait-bound.rs:8:7
|
||||
|
|
||||
LL | fn do_stuff<T : Bar>(t : T) {
|
||||
| - method `foo` not found for this type parameter
|
||||
LL | t.foo()
|
||||
| ^^^ method not found in `T`
|
||||
|
|
||||
|
@ -1,6 +1,8 @@
|
||||
error[E0599]: no method named `clone` found for type parameter `T` in the current scope
|
||||
--> $DIR/issue-95898.rs:5:7
|
||||
|
|
||||
LL | fn foo<T:>(t: T) {
|
||||
| - method `clone` not found for this type parameter
|
||||
LL | t.clone();
|
||||
| ^^^^^ method not found in `T`
|
||||
|
|
||||
|
@ -2,7 +2,7 @@ error[E0599]: no method named `a` found for struct `S` in the current scope
|
||||
--> $DIR/item-privacy.rs:67:7
|
||||
|
|
||||
LL | struct S;
|
||||
| --------- method `a` not found for this
|
||||
| - method `a` not found for this struct
|
||||
...
|
||||
LL | S.a();
|
||||
| ^ method not found in `S`
|
||||
@ -18,7 +18,7 @@ error[E0599]: no method named `b` found for struct `S` in the current scope
|
||||
--> $DIR/item-privacy.rs:68:7
|
||||
|
|
||||
LL | struct S;
|
||||
| --------- method `b` not found for this
|
||||
| - method `b` not found for this struct
|
||||
...
|
||||
LL | fn b(&self) { }
|
||||
| - the method is available for `S` here
|
||||
@ -45,7 +45,7 @@ error[E0599]: no function or associated item named `a` found for struct `S` in t
|
||||
--> $DIR/item-privacy.rs:78:8
|
||||
|
|
||||
LL | struct S;
|
||||
| --------- function or associated item `a` not found for this
|
||||
| - function or associated item `a` not found for this struct
|
||||
...
|
||||
LL | S::a(&S);
|
||||
| ^ function or associated item not found in `S`
|
||||
@ -61,7 +61,7 @@ error[E0599]: no function or associated item named `b` found for struct `S` in t
|
||||
--> $DIR/item-privacy.rs:80:8
|
||||
|
|
||||
LL | struct S;
|
||||
| --------- function or associated item `b` not found for this
|
||||
| - function or associated item `b` not found for this struct
|
||||
...
|
||||
LL | S::b(&S);
|
||||
| ^ function or associated item not found in `S`
|
||||
@ -85,7 +85,7 @@ error[E0599]: no associated item named `A` found for struct `S` in the current s
|
||||
--> $DIR/item-privacy.rs:97:8
|
||||
|
|
||||
LL | struct S;
|
||||
| --------- associated item `A` not found for this
|
||||
| - associated item `A` not found for this struct
|
||||
...
|
||||
LL | S::A;
|
||||
| ^ associated item not found in `S`
|
||||
@ -101,7 +101,7 @@ error[E0599]: no associated item named `B` found for struct `S` in the current s
|
||||
--> $DIR/item-privacy.rs:98:8
|
||||
|
|
||||
LL | struct S;
|
||||
| --------- associated item `B` not found for this
|
||||
| - associated item `B` not found for this struct
|
||||
...
|
||||
LL | S::B;
|
||||
| ^ associated item not found in `S`
|
||||
|
@ -2,7 +2,7 @@ error[E0599]: no method named `clone` found for struct `Qux` in the current scop
|
||||
--> $DIR/explicitly-unimplemented-error-message.rs:34:9
|
||||
|
|
||||
LL | struct Qux;
|
||||
| ----------- method `clone` not found for this
|
||||
| --- method `clone` not found for this struct
|
||||
...
|
||||
LL | Qux.clone();
|
||||
| ^^^^^ method not found in `Qux`
|
||||
@ -23,7 +23,7 @@ error[E0599]: no method named `foo` found for struct `Qux` in the current scope
|
||||
--> $DIR/explicitly-unimplemented-error-message.rs:44:9
|
||||
|
|
||||
LL | struct Qux;
|
||||
| ----------- method `foo` not found for this
|
||||
| --- method `foo` not found for this struct
|
||||
...
|
||||
LL | Qux.foo();
|
||||
| ^^^ method not found in `Qux`
|
||||
|
17
src/test/ui/typeck/point-at-type-parameter-definition.rs
Normal file
17
src/test/ui/typeck/point-at-type-parameter-definition.rs
Normal file
@ -0,0 +1,17 @@
|
||||
trait Trait {
|
||||
fn do_stuff(&self);
|
||||
}
|
||||
|
||||
struct Hello;
|
||||
|
||||
impl Hello {
|
||||
fn method(&self) {}
|
||||
}
|
||||
|
||||
impl<Hello> Trait for Vec<Hello> {
|
||||
fn do_stuff(&self) {
|
||||
self[0].method(); //~ ERROR no method named `method` found for type parameter `Hello` in the current scope
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
12
src/test/ui/typeck/point-at-type-parameter-definition.stderr
Normal file
12
src/test/ui/typeck/point-at-type-parameter-definition.stderr
Normal file
@ -0,0 +1,12 @@
|
||||
error[E0599]: no method named `method` found for type parameter `Hello` in the current scope
|
||||
--> $DIR/point-at-type-parameter-definition.rs:13:17
|
||||
|
|
||||
LL | impl<Hello> Trait for Vec<Hello> {
|
||||
| ----- method `method` not found for this type parameter
|
||||
LL | fn do_stuff(&self) {
|
||||
LL | self[0].method();
|
||||
| ^^^^^^ method not found in `Hello`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0599`.
|
@ -3,8 +3,8 @@ error[E0599]: the method `clone` exists for union `U5<CloneNoCopy>`, but its tra
|
||||
|
|
||||
LL | union U5<T> {
|
||||
| -----------
|
||||
| |
|
||||
| method `clone` not found for this
|
||||
| | |
|
||||
| | method `clone` not found for this union
|
||||
| doesn't satisfy `U5<CloneNoCopy>: Clone`
|
||||
...
|
||||
LL | struct CloneNoCopy;
|
||||
|
@ -3,8 +3,8 @@ error[E0599]: the method `clone` exists for union `U5<CloneNoCopy>`, but its tra
|
||||
|
|
||||
LL | union U5<T> {
|
||||
| -----------
|
||||
| |
|
||||
| method `clone` not found for this
|
||||
| | |
|
||||
| | method `clone` not found for this union
|
||||
| doesn't satisfy `U5<CloneNoCopy>: Clone`
|
||||
...
|
||||
LL | struct CloneNoCopy;
|
||||
|
Loading…
x
Reference in New Issue
Block a user