mirror of https://github.com/rust-lang/rust.git
Auto merge of #129595 - matthiaskrgr:rollup-4udn7nn, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - #129288 (Use subtyping for `UnsafeFnPointer` coercion, too) - #129405 (Fixing span manipulation and indentation of the suggestion introduced by #126187) - #129518 (gitignore: ignore ICE reports regardless of directory) - #129519 (Remove redundant flags from `lower_ty_common` that can be inferred from the HIR) - #129525 (rustdoc: clean up tuple <-> primitive conversion docs) - #129526 (Use `FxHasher` on new solver unconditionally) - #129544 (Removes dead code from the compiler) - #129553 (add back test for stable-const-can-only-call-stable-const) - #129590 (Avoid taking reference of &TyKind) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
f48062e7d0
|
@ -56,7 +56,9 @@ build/
|
|||
/src/tools/x/target
|
||||
# Created by default with `src/ci/docker/run.sh`
|
||||
/obj/
|
||||
/rustc-ice*
|
||||
|
||||
## ICE reports
|
||||
rustc-ice-*.txt
|
||||
|
||||
## Temporary files
|
||||
*~
|
||||
|
|
|
@ -4536,6 +4536,7 @@ dependencies = [
|
|||
"bitflags 2.6.0",
|
||||
"derive-where",
|
||||
"indexmap",
|
||||
"rustc-hash",
|
||||
"rustc_ast_ir",
|
||||
"rustc_data_structures",
|
||||
"rustc_index",
|
||||
|
|
|
@ -290,7 +290,7 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
|
|||
ty: Ty<'_>,
|
||||
is_index: Option<bool>,
|
||||
) -> Diag<'infcx> {
|
||||
let type_name = match (&ty.kind(), is_index) {
|
||||
let type_name = match (ty.kind(), is_index) {
|
||||
(&ty::Array(_, _), Some(true)) | (&ty::Array(_, _), None) => "array",
|
||||
(&ty::Slice(_), _) => "slice",
|
||||
_ => span_bug!(move_from_span, "this path should not cause illegal move"),
|
||||
|
|
|
@ -201,7 +201,7 @@ fn place_components_conflict<'tcx>(
|
|||
|
||||
let base_ty = base.ty(body, tcx).ty;
|
||||
|
||||
match (elem, &base_ty.kind(), access) {
|
||||
match (elem, base_ty.kind(), access) {
|
||||
(_, _, Shallow(Some(ArtificialField::ArrayLength)))
|
||||
| (_, _, Shallow(Some(ArtificialField::FakeBorrow))) => {
|
||||
// The array length is like additional fields on the
|
||||
|
|
|
@ -2043,9 +2043,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||
|
||||
let ty_fn_ptr_from = tcx.safe_to_unsafe_fn_ty(fn_sig);
|
||||
|
||||
if let Err(terr) = self.eq_types(
|
||||
*ty,
|
||||
if let Err(terr) = self.sub_types(
|
||||
ty_fn_ptr_from,
|
||||
*ty,
|
||||
location.to_locations(),
|
||||
ConstraintCategory::Cast { unsize_to: None },
|
||||
) {
|
||||
|
|
|
@ -419,7 +419,7 @@ const_eval_unstable_const_fn = `{$def_path}` is not yet stable as a const fn
|
|||
const_eval_unstable_in_stable =
|
||||
const-stable function cannot use `#[feature({$gate})]`
|
||||
.unstable_sugg = if it is not part of the public API, make this function unstably const
|
||||
.bypass_sugg = otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks
|
||||
.bypass_sugg = otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (but requires team approval)
|
||||
|
||||
const_eval_unterminated_c_string =
|
||||
reading a null-terminated string starting at {$pointer} with no null found before end of allocation
|
||||
|
|
|
@ -388,7 +388,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
let (src_pointee_ty, dest_pointee_ty) =
|
||||
self.tcx.struct_lockstep_tails_for_codegen(source_ty, cast_ty, self.param_env);
|
||||
|
||||
match (&src_pointee_ty.kind(), &dest_pointee_ty.kind()) {
|
||||
match (src_pointee_ty.kind(), dest_pointee_ty.kind()) {
|
||||
(&ty::Array(_, length), &ty::Slice(_)) => {
|
||||
let ptr = self.read_pointer(src)?;
|
||||
let val = Immediate::new_slice(
|
||||
|
@ -478,9 +478,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
dest: &PlaceTy<'tcx, M::Provenance>,
|
||||
) -> InterpResult<'tcx> {
|
||||
trace!("Unsizing {:?} of type {} into {}", *src, src.layout.ty, cast_ty.ty);
|
||||
match (&src.layout.ty.kind(), &cast_ty.ty.kind()) {
|
||||
match (src.layout.ty.kind(), cast_ty.ty.kind()) {
|
||||
(&ty::Ref(_, s, _), &ty::Ref(_, c, _) | &ty::RawPtr(c, _))
|
||||
| (&ty::RawPtr(s, _), &ty::RawPtr(c, _)) => self.unsize_into_ptr(src, dest, *s, *c),
|
||||
| (&ty::RawPtr(s, _), &ty::RawPtr(c, _)) => self.unsize_into_ptr(src, dest, s, c),
|
||||
(&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => {
|
||||
assert_eq!(def_a, def_b); // implies same number of fields
|
||||
|
||||
|
|
|
@ -392,7 +392,7 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
|
|||
}
|
||||
|
||||
fn re_infer(&self, span: Span, reason: RegionInferReason<'_>) -> ty::Region<'tcx> {
|
||||
if let RegionInferReason::BorrowedObjectLifetimeDefault = reason {
|
||||
if let RegionInferReason::ObjectLifetimeDefault = reason {
|
||||
let e = struct_span_code_err!(
|
||||
self.dcx(),
|
||||
span,
|
||||
|
|
|
@ -608,7 +608,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
|
||||
let mut bound_span_label = |self_ty: Ty<'_>, obligation: &str, quiet: &str| {
|
||||
let msg = format!("`{}`", if obligation.len() > 50 { quiet } else { obligation });
|
||||
match &self_ty.kind() {
|
||||
match self_ty.kind() {
|
||||
// Point at the type that couldn't satisfy the bound.
|
||||
ty::Adt(def, _) => {
|
||||
bound_spans.get_mut_or_insert_default(tcx.def_span(def.did())).push(msg)
|
||||
|
|
|
@ -15,11 +15,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
///
|
||||
/// *Bare* trait object types are ones that aren't preceded by the keyword `dyn`.
|
||||
/// In edition 2021 and onward we emit a hard error for them.
|
||||
pub(super) fn prohibit_or_lint_bare_trait_object_ty(
|
||||
&self,
|
||||
self_ty: &hir::Ty<'_>,
|
||||
in_path: bool,
|
||||
) {
|
||||
pub(super) fn prohibit_or_lint_bare_trait_object_ty(&self, self_ty: &hir::Ty<'_>) {
|
||||
let tcx = self.tcx();
|
||||
|
||||
let hir::TyKind::TraitObject([poly_trait_ref, ..], _, TraitObjectSyntax::None) =
|
||||
|
@ -28,6 +24,21 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
return;
|
||||
};
|
||||
|
||||
let in_path = match tcx.parent_hir_node(self_ty.hir_id) {
|
||||
hir::Node::Ty(hir::Ty {
|
||||
kind: hir::TyKind::Path(hir::QPath::TypeRelative(qself, _)),
|
||||
..
|
||||
})
|
||||
| hir::Node::Expr(hir::Expr {
|
||||
kind: hir::ExprKind::Path(hir::QPath::TypeRelative(qself, _)),
|
||||
..
|
||||
})
|
||||
| hir::Node::Pat(hir::Pat {
|
||||
kind: hir::PatKind::Path(hir::QPath::TypeRelative(qself, _)),
|
||||
..
|
||||
}) if qself.hir_id == self_ty.hir_id => true,
|
||||
_ => false,
|
||||
};
|
||||
let needs_bracket = in_path
|
||||
&& !tcx
|
||||
.sess
|
||||
|
|
|
@ -85,10 +85,9 @@ pub enum PredicateFilter {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub enum RegionInferReason<'a> {
|
||||
/// Lifetime on a trait object behind a reference.
|
||||
/// This allows inferring information from the reference.
|
||||
BorrowedObjectLifetimeDefault,
|
||||
/// A trait object's lifetime.
|
||||
/// Lifetime on a trait object that is spelled explicitly, e.g. `+ 'a` or `+ '_`.
|
||||
ExplicitObjectLifetime,
|
||||
/// A trait object's lifetime when it is elided, e.g. `dyn Any`.
|
||||
ObjectLifetimeDefault,
|
||||
/// Generic lifetime parameter
|
||||
Param(&'a ty::GenericParamDef),
|
||||
|
@ -1057,7 +1056,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
|
||||
// Find the type of the associated item, and the trait where the associated
|
||||
// item is declared.
|
||||
let bound = match (&qself_ty.kind(), qself_res) {
|
||||
let bound = match (qself_ty.kind(), qself_res) {
|
||||
(_, Res::SelfTyAlias { alias_to: impl_def_id, is_trait_impl: true, .. }) => {
|
||||
// `Self` in an impl of a trait -- we have a concrete self type and a
|
||||
// trait reference.
|
||||
|
@ -1999,16 +1998,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
}
|
||||
}
|
||||
|
||||
/// Lower a type from the HIR to our internal notion of a type.
|
||||
pub fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
|
||||
self.lower_ty_common(hir_ty, false, false)
|
||||
}
|
||||
|
||||
/// Lower a type inside of a path from the HIR to our internal notion of a type.
|
||||
pub fn lower_ty_in_path(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
|
||||
self.lower_ty_common(hir_ty, false, true)
|
||||
}
|
||||
|
||||
fn lower_delegation_ty(&self, idx: hir::InferDelegationKind) -> Ty<'tcx> {
|
||||
let delegation_sig = self.tcx().inherit_sig_for_delegation_item(self.item_def_id());
|
||||
match idx {
|
||||
|
@ -2026,7 +2015,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
/// 2. `in_path`: Whether the type appears inside of a path.
|
||||
/// Used to provide correct diagnostics for bare trait object types.
|
||||
#[instrument(level = "debug", skip(self), ret)]
|
||||
fn lower_ty_common(&self, hir_ty: &hir::Ty<'tcx>, borrowed: bool, in_path: bool) -> Ty<'tcx> {
|
||||
pub fn lower_ty(&self, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
|
||||
let tcx = self.tcx();
|
||||
|
||||
let result_ty = match &hir_ty.kind {
|
||||
|
@ -2036,7 +2025,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
hir::TyKind::Ref(region, mt) => {
|
||||
let r = self.lower_lifetime(region, RegionInferReason::Reference);
|
||||
debug!(?r);
|
||||
let t = self.lower_ty_common(mt.ty, true, false);
|
||||
let t = self.lower_ty(mt.ty);
|
||||
Ty::new_ref(tcx, r, t, mt.mutbl)
|
||||
}
|
||||
hir::TyKind::Never => tcx.types.never,
|
||||
|
@ -2065,20 +2054,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
)
|
||||
}
|
||||
hir::TyKind::TraitObject(bounds, lifetime, repr) => {
|
||||
self.prohibit_or_lint_bare_trait_object_ty(hir_ty, in_path);
|
||||
self.prohibit_or_lint_bare_trait_object_ty(hir_ty);
|
||||
|
||||
let repr = match repr {
|
||||
TraitObjectSyntax::Dyn | TraitObjectSyntax::None => ty::Dyn,
|
||||
TraitObjectSyntax::DynStar => ty::DynStar,
|
||||
};
|
||||
self.lower_trait_object_ty(
|
||||
hir_ty.span,
|
||||
hir_ty.hir_id,
|
||||
bounds,
|
||||
lifetime,
|
||||
borrowed,
|
||||
repr,
|
||||
)
|
||||
self.lower_trait_object_ty(hir_ty.span, hir_ty.hir_id, bounds, lifetime, repr)
|
||||
}
|
||||
hir::TyKind::Path(hir::QPath::Resolved(maybe_qself, path)) => {
|
||||
debug!(?maybe_qself, ?path);
|
||||
|
@ -2106,7 +2088,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
}
|
||||
hir::TyKind::Path(hir::QPath::TypeRelative(qself, segment)) => {
|
||||
debug!(?qself, ?segment);
|
||||
let ty = self.lower_ty_common(qself, false, true);
|
||||
let ty = self.lower_ty(qself);
|
||||
self.lower_assoc_path(hir_ty.hir_id, hir_ty.span, ty, qself, segment, false)
|
||||
.map(|(ty, _, _)| ty)
|
||||
.unwrap_or_else(|guar| Ty::new_error(tcx, guar))
|
||||
|
|
|
@ -30,7 +30,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
hir_id: hir::HirId,
|
||||
hir_trait_bounds: &[(hir::PolyTraitRef<'tcx>, hir::TraitBoundModifier)],
|
||||
lifetime: &hir::Lifetime,
|
||||
borrowed: bool,
|
||||
representation: DynKind,
|
||||
) -> Ty<'tcx> {
|
||||
let tcx = self.tcx();
|
||||
|
@ -325,22 +324,32 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
|||
v.dedup();
|
||||
let existential_predicates = tcx.mk_poly_existential_predicates(&v);
|
||||
|
||||
// Use explicitly-specified region bound.
|
||||
// Use explicitly-specified region bound, unless the bound is missing.
|
||||
let region_bound = if !lifetime.is_elided() {
|
||||
self.lower_lifetime(lifetime, RegionInferReason::ObjectLifetimeDefault)
|
||||
self.lower_lifetime(lifetime, RegionInferReason::ExplicitObjectLifetime)
|
||||
} else {
|
||||
self.compute_object_lifetime_bound(span, existential_predicates).unwrap_or_else(|| {
|
||||
// Curiously, we prefer object lifetime default for `+ '_`...
|
||||
if tcx.named_bound_var(lifetime.hir_id).is_some() {
|
||||
self.lower_lifetime(lifetime, RegionInferReason::ObjectLifetimeDefault)
|
||||
self.lower_lifetime(lifetime, RegionInferReason::ExplicitObjectLifetime)
|
||||
} else {
|
||||
self.re_infer(
|
||||
span,
|
||||
if borrowed {
|
||||
RegionInferReason::ObjectLifetimeDefault
|
||||
let reason =
|
||||
if let hir::LifetimeName::ImplicitObjectLifetimeDefault = lifetime.res {
|
||||
if let hir::Node::Ty(hir::Ty {
|
||||
kind: hir::TyKind::Ref(parent_lifetime, _),
|
||||
..
|
||||
}) = tcx.parent_hir_node(hir_id)
|
||||
&& tcx.named_bound_var(parent_lifetime.hir_id).is_none()
|
||||
{
|
||||
// Parent lifetime must have failed to resolve. Don't emit a redundant error.
|
||||
RegionInferReason::ExplicitObjectLifetime
|
||||
} else {
|
||||
RegionInferReason::ObjectLifetimeDefault
|
||||
}
|
||||
} else {
|
||||
RegionInferReason::BorrowedObjectLifetimeDefault
|
||||
},
|
||||
)
|
||||
RegionInferReason::ExplicitObjectLifetime
|
||||
};
|
||||
self.re_infer(span, reason)
|
||||
}
|
||||
})
|
||||
};
|
||||
|
|
|
@ -798,7 +798,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// to be object-safe.
|
||||
// We manually call `register_wf_obligation` in the success path
|
||||
// below.
|
||||
let ty = self.lowerer().lower_ty_in_path(qself);
|
||||
let ty = self.lowerer().lower_ty(qself);
|
||||
(LoweredTy::from_raw(self, span, ty), qself, segment)
|
||||
}
|
||||
QPath::LangItem(..) => {
|
||||
|
|
|
@ -2975,7 +2975,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
let mut suffix_suggestion = sugg.clone();
|
||||
suffix_suggestion.push((
|
||||
if matches!(
|
||||
(&expected_ty.kind(), &checked_ty.kind()),
|
||||
(expected_ty.kind(), checked_ty.kind()),
|
||||
(ty::Int(_) | ty::Uint(_), ty::Float(_))
|
||||
) {
|
||||
// Remove fractional part from literal, for example `42.0f32` into `42`
|
||||
|
@ -3077,7 +3077,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
err.multipart_suggestion_verbose(msg, suggestion, Applicability::MachineApplicable);
|
||||
};
|
||||
|
||||
match (&expected_ty.kind(), &checked_ty.kind()) {
|
||||
match (expected_ty.kind(), checked_ty.kind()) {
|
||||
(ty::Int(exp), ty::Int(found)) => {
|
||||
let (f2e_is_fallible, e2f_is_fallible) = match (exp.bit_width(), found.bit_width())
|
||||
{
|
||||
|
|
|
@ -1012,7 +1012,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
};
|
||||
let mut bound_span_label = |self_ty: Ty<'_>, obligation: &str, quiet: &str| {
|
||||
let msg = format!("`{}`", if obligation.len() > 50 { quiet } else { obligation });
|
||||
match &self_ty.kind() {
|
||||
match self_ty.kind() {
|
||||
// Point at the type that couldn't satisfy the bound.
|
||||
ty::Adt(def, _) => {
|
||||
bound_spans.get_mut_or_insert_default(tcx.def_span(def.did())).push(msg)
|
||||
|
|
|
@ -1336,7 +1336,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// More generally, the expected type wants a tuple variant with one field of an
|
||||
// N-arity-tuple, e.g., `V_i((p_0, .., p_N))`. Meanwhile, the user supplied a pattern
|
||||
// with the subpatterns directly in the tuple variant pattern, e.g., `V_i(p_0, .., p_N)`.
|
||||
let missing_parentheses = match (&expected.kind(), fields, had_err) {
|
||||
let missing_parentheses = match (expected.kind(), fields, had_err) {
|
||||
// #67037: only do this if we could successfully type-check the expected type against
|
||||
// the tuple struct pattern. Otherwise the args could get out of range on e.g.,
|
||||
// `let P() = U;` where `P != U` with `struct P<T>(T);`.
|
||||
|
|
|
@ -99,6 +99,4 @@ incremental_unrecognized_depnode = unrecognized `DepNode` variant: {$name}
|
|||
|
||||
incremental_unrecognized_depnode_label = dep-node label `{$label}` not recognized
|
||||
|
||||
incremental_write_dep_graph = failed to write dependency graph to `{$path}`: {$err}
|
||||
|
||||
incremental_write_new = failed to write {$name} to `{$path}`: {$err}
|
||||
|
|
|
@ -272,13 +272,6 @@ pub struct LoadDepGraph {
|
|||
pub err: std::io::Error,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_write_dep_graph)]
|
||||
pub struct WriteDepGraph<'a> {
|
||||
pub path: &'a Path,
|
||||
pub err: std::io::Error,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(incremental_move_dep_graph)]
|
||||
pub struct MoveDepGraph<'a> {
|
||||
|
|
|
@ -1104,7 +1104,7 @@ where
|
|||
}
|
||||
|
||||
fn is_never(this: TyAndLayout<'tcx>) -> bool {
|
||||
this.ty.kind() == &ty::Never
|
||||
matches!(this.ty.kind(), ty::Never)
|
||||
}
|
||||
|
||||
fn is_tuple(this: TyAndLayout<'tcx>) -> bool {
|
||||
|
|
|
@ -296,7 +296,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
) -> (Ty<'tcx>, Ty<'tcx>) {
|
||||
let (mut a, mut b) = (source, target);
|
||||
loop {
|
||||
match (&a.kind(), &b.kind()) {
|
||||
match (a.kind(), b.kind()) {
|
||||
(&ty::Adt(a_def, a_args), &ty::Adt(b_def, b_args))
|
||||
if a_def == b_def && a_def.is_struct() =>
|
||||
{
|
||||
|
|
|
@ -127,7 +127,7 @@ fn lit_to_mir_constant<'tcx>(
|
|||
Ok(ConstValue::Scalar(Scalar::from_uint(result, width)))
|
||||
};
|
||||
|
||||
let value = match (lit, &ty.kind()) {
|
||||
let value = match (lit, ty.kind()) {
|
||||
(ast::LitKind::Str(s, _), ty::Ref(_, inner_ty, _)) if inner_ty.is_str() => {
|
||||
let s = s.as_str();
|
||||
let allocation = Allocation::from_bytes_byte_aligned_immutable(s.as_bytes());
|
||||
|
|
|
@ -29,7 +29,7 @@ pub(crate) fn lit_to_const<'tcx>(
|
|||
.unwrap_or_else(|| bug!("expected to create ScalarInt from uint {:?}", result)))
|
||||
};
|
||||
|
||||
let valtree = match (lit, &ty.kind()) {
|
||||
let valtree = match (lit, ty.kind()) {
|
||||
(ast::LitKind::Str(s, _), ty::Ref(_, inner_ty, _)) if inner_ty.is_str() => {
|
||||
let str_bytes = s.as_str().as_bytes();
|
||||
ty::ValTree::from_raw_bytes(tcx, str_bytes)
|
||||
|
|
|
@ -1035,9 +1035,9 @@ fn find_vtable_types_for_unsizing<'tcx>(
|
|||
}
|
||||
};
|
||||
|
||||
match (&source_ty.kind(), &target_ty.kind()) {
|
||||
match (source_ty.kind(), target_ty.kind()) {
|
||||
(&ty::Ref(_, a, _), &ty::Ref(_, b, _) | &ty::RawPtr(b, _))
|
||||
| (&ty::RawPtr(a, _), &ty::RawPtr(b, _)) => ptr_vtable(*a, *b),
|
||||
| (&ty::RawPtr(a, _), &ty::RawPtr(b, _)) => ptr_vtable(a, b),
|
||||
(&ty::Adt(def_a, _), &ty::Adt(def_b, _)) if def_a.is_box() && def_b.is_box() => {
|
||||
ptr_vtable(source_ty.boxed_ty(), target_ty.boxed_ty())
|
||||
}
|
||||
|
|
|
@ -481,10 +481,6 @@ passes_must_not_suspend =
|
|||
`must_not_suspend` attribute should be applied to a struct, enum, union, or trait
|
||||
.label = is not a struct, enum, union, or trait
|
||||
|
||||
passes_must_use_async =
|
||||
`must_use` attribute on `async` functions applies to the anonymous `Future` returned by the function, not the value within
|
||||
.label = this attribute does nothing, the `Future`s returned by async functions are already `must_use`
|
||||
|
||||
passes_must_use_no_effect =
|
||||
`#[must_use]` has no effect when applied to {$article} {$target}
|
||||
|
||||
|
|
|
@ -952,6 +952,16 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
bare_fn_ty.decl.inputs.len() == 1
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|| if let Some(&[hir::GenericArg::Type(ty)]) = i
|
||||
.of_trait
|
||||
.as_ref()
|
||||
.and_then(|trait_ref| trait_ref.path.segments.last())
|
||||
.map(|last_segment| last_segment.args().args)
|
||||
{
|
||||
matches!(&ty.kind, hir::TyKind::Tup([_]))
|
||||
} else {
|
||||
false
|
||||
};
|
||||
if !is_valid {
|
||||
self.dcx().emit_err(errors::DocFakeVariadicNotValid { span: meta.span() });
|
||||
|
|
|
@ -371,13 +371,6 @@ pub struct FfiConstInvalidTarget {
|
|||
pub attr_span: Span,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(passes_must_use_async)]
|
||||
pub struct MustUseAsync {
|
||||
#[label]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(passes_must_use_no_effect)]
|
||||
pub struct MustUseNoEffect {
|
||||
|
|
|
@ -382,7 +382,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||
if !expected_inner.is_fn() || !found_inner.is_fn() {
|
||||
return;
|
||||
}
|
||||
match (&expected_inner.kind(), &found_inner.kind()) {
|
||||
match (expected_inner.kind(), found_inner.kind()) {
|
||||
(ty::FnPtr(sig_tys, hdr), ty::FnDef(did, args)) => {
|
||||
let sig = sig_tys.with(*hdr);
|
||||
let expected_sig = &(self.normalize_fn_sig)(sig);
|
||||
|
|
|
@ -4702,10 +4702,15 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||
if let hir::ExprKind::Block(b, _) = body.value.kind
|
||||
&& b.expr.is_none()
|
||||
{
|
||||
// The span of '}' in the end of block.
|
||||
let span = self.tcx.sess.source_map().end_point(b.span);
|
||||
sugg_spans.push((
|
||||
// The span will point to the closing curly brace `}` of the block.
|
||||
b.span.shrink_to_hi().with_lo(b.span.hi() - BytePos(1)),
|
||||
"\n Ok(())\n}".to_string(),
|
||||
span.shrink_to_lo(),
|
||||
format!(
|
||||
"{}{}",
|
||||
" Ok(())\n",
|
||||
self.tcx.sess.source_map().indentation_before(span).unwrap_or_default(),
|
||||
),
|
||||
));
|
||||
}
|
||||
err.multipart_suggestion_verbose(
|
||||
|
|
|
@ -4,7 +4,6 @@ use crate::layout;
|
|||
pub(crate) trait QueryContext {
|
||||
type Def: layout::Def;
|
||||
type Ref: layout::Ref;
|
||||
type Scope: Copy;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -28,20 +27,17 @@ pub(crate) mod test {
|
|||
impl QueryContext for UltraMinimal {
|
||||
type Def = Def;
|
||||
type Ref = !;
|
||||
type Scope = ();
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rustc")]
|
||||
mod rustc {
|
||||
use rustc_middle::ty::{Ty, TyCtxt};
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
|
||||
use super::*;
|
||||
|
||||
impl<'tcx> super::QueryContext for TyCtxt<'tcx> {
|
||||
type Def = layout::rustc::Def<'tcx>;
|
||||
type Ref = layout::rustc::Ref<'tcx>;
|
||||
|
||||
type Scope = Ty<'tcx>;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ edition = "2021"
|
|||
bitflags = "2.4.1"
|
||||
derive-where = "1.2.7"
|
||||
indexmap = "2.0.0"
|
||||
rustc-hash = "1.1.0"
|
||||
rustc_ast_ir = { path = "../rustc_ast_ir", default-features = false }
|
||||
rustc_data_structures = { path = "../rustc_data_structures", optional = true }
|
||||
rustc_index = { path = "../rustc_index", default-features = false }
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
use std::hash::BuildHasherDefault;
|
||||
|
||||
use rustc_hash::FxHasher;
|
||||
pub use rustc_hash::{FxHashMap as HashMap, FxHashSet as HashSet};
|
||||
|
||||
pub type IndexMap<K, V> = indexmap::IndexMap<K, V, BuildHasherDefault<FxHasher>>;
|
||||
pub type IndexSet<V> = indexmap::IndexSet<V, BuildHasherDefault<FxHasher>>;
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
mod impl_ {
|
||||
pub use rustc_data_structures::fx::{
|
||||
FxHashMap as HashMap, FxHashSet as HashSet, FxIndexMap as IndexMap, FxIndexSet as IndexSet,
|
||||
};
|
||||
pub use rustc_data_structures::sso::{SsoHashMap, SsoHashSet};
|
||||
pub use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
pub use rustc_data_structures::sync::Lrc;
|
||||
|
@ -10,11 +15,9 @@ mod impl_ {
|
|||
|
||||
#[cfg(not(feature = "nightly"))]
|
||||
mod impl_ {
|
||||
pub use std::collections::{HashMap, HashMap as SsoHashMap, HashSet, HashSet as SsoHashSet};
|
||||
pub use std::collections::{HashMap as SsoHashMap, HashSet as SsoHashSet};
|
||||
pub use std::sync::Arc as Lrc;
|
||||
|
||||
pub use indexmap::{IndexMap, IndexSet};
|
||||
|
||||
#[inline]
|
||||
pub fn ensure_sufficient_stack<R>(f: impl FnOnce() -> R) -> R {
|
||||
f()
|
||||
|
|
|
@ -59,6 +59,7 @@ fn box_deref_lval() {
|
|||
assert_eq!(x.get(), 1000);
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub struct ConstAllocator;
|
||||
|
||||
unsafe impl Allocator for ConstAllocator {
|
||||
|
|
|
@ -122,23 +122,29 @@ macro_rules! tuple_impls {
|
|||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "array_tuple_conv", since = "1.71.0")]
|
||||
impl<T> From<[T; ${count($T)}]> for ($(${ignore($T)} T,)+) {
|
||||
#[inline]
|
||||
#[allow(non_snake_case)]
|
||||
fn from(array: [T; ${count($T)}]) -> Self {
|
||||
let [$($T,)+] = array;
|
||||
($($T,)+)
|
||||
maybe_tuple_doc! {
|
||||
$($T)+ @
|
||||
#[stable(feature = "array_tuple_conv", since = "1.71.0")]
|
||||
impl<T> From<[T; ${count($T)}]> for ($(${ignore($T)} T,)+) {
|
||||
#[inline]
|
||||
#[allow(non_snake_case)]
|
||||
fn from(array: [T; ${count($T)}]) -> Self {
|
||||
let [$($T,)+] = array;
|
||||
($($T,)+)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "array_tuple_conv", since = "1.71.0")]
|
||||
impl<T> From<($(${ignore($T)} T,)+)> for [T; ${count($T)}] {
|
||||
#[inline]
|
||||
#[allow(non_snake_case)]
|
||||
fn from(tuple: ($(${ignore($T)} T,)+)) -> Self {
|
||||
let ($($T,)+) = tuple;
|
||||
[$($T,)+]
|
||||
maybe_tuple_doc! {
|
||||
$($T)+ @
|
||||
#[stable(feature = "array_tuple_conv", since = "1.71.0")]
|
||||
impl<T> From<($(${ignore($T)} T,)+)> for [T; ${count($T)}] {
|
||||
#[inline]
|
||||
#[allow(non_snake_case)]
|
||||
fn from(tuple: ($(${ignore($T)} T,)+)) -> Self {
|
||||
let ($($T,)+) = tuple;
|
||||
[$($T,)+]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -148,7 +154,7 @@ macro_rules! tuple_impls {
|
|||
// Otherwise, it hides the docs entirely.
|
||||
macro_rules! maybe_tuple_doc {
|
||||
($a:ident @ #[$meta:meta] $item:item) => {
|
||||
#[doc(fake_variadic)]
|
||||
#[cfg_attr(not(bootstrap), doc(fake_variadic))]
|
||||
#[doc = "This trait is implemented for tuples up to twelve items long."]
|
||||
#[$meta]
|
||||
$item
|
||||
|
|
|
@ -1288,56 +1288,90 @@ impl clean::Impl {
|
|||
if self.is_negative_trait_impl() {
|
||||
write!(f, "!")?;
|
||||
}
|
||||
ty.print(cx).fmt(f)?;
|
||||
if self.kind.is_fake_variadic()
|
||||
&& let generics = ty.generics()
|
||||
&& let &[inner_type] = generics.as_ref().map_or(&[][..], |v| &v[..])
|
||||
{
|
||||
let last = ty.last();
|
||||
if f.alternate() {
|
||||
write!(f, "{}<", last)?;
|
||||
self.print_type(inner_type, f, use_absolute, cx)?;
|
||||
write!(f, ">")?;
|
||||
} else {
|
||||
write!(f, "{}<", anchor(ty.def_id(), last, cx).to_string())?;
|
||||
self.print_type(inner_type, f, use_absolute, cx)?;
|
||||
write!(f, ">")?;
|
||||
}
|
||||
} else {
|
||||
ty.print(cx).fmt(f)?;
|
||||
}
|
||||
write!(f, " for ")?;
|
||||
}
|
||||
|
||||
if let clean::Type::Tuple(types) = &self.for_
|
||||
&& let [clean::Type::Generic(name)] = &types[..]
|
||||
&& (self.kind.is_fake_variadic() || self.kind.is_auto())
|
||||
{
|
||||
// Hardcoded anchor library/core/src/primitive_docs.rs
|
||||
// Link should match `# Trait implementations`
|
||||
primitive_link_fragment(
|
||||
f,
|
||||
PrimitiveType::Tuple,
|
||||
format_args!("({name}₁, {name}₂, …, {name}ₙ)"),
|
||||
"#trait-implementations-1",
|
||||
cx,
|
||||
)?;
|
||||
} else if let clean::BareFunction(bare_fn) = &self.for_
|
||||
&& let [clean::Argument { type_: clean::Type::Generic(name), .. }] =
|
||||
&bare_fn.decl.inputs.values[..]
|
||||
&& (self.kind.is_fake_variadic() || self.kind.is_auto())
|
||||
{
|
||||
// Hardcoded anchor library/core/src/primitive_docs.rs
|
||||
// Link should match `# Trait implementations`
|
||||
|
||||
print_higher_ranked_params_with_space(&bare_fn.generic_params, cx).fmt(f)?;
|
||||
bare_fn.safety.print_with_space().fmt(f)?;
|
||||
print_abi_with_space(bare_fn.abi).fmt(f)?;
|
||||
let ellipsis = if bare_fn.decl.c_variadic { ", ..." } else { "" };
|
||||
primitive_link_fragment(
|
||||
f,
|
||||
PrimitiveType::Tuple,
|
||||
format_args!("fn({name}₁, {name}₂, …, {name}ₙ{ellipsis})"),
|
||||
"#trait-implementations-1",
|
||||
cx,
|
||||
)?;
|
||||
// Write output.
|
||||
if !bare_fn.decl.output.is_unit() {
|
||||
write!(f, " -> ")?;
|
||||
fmt_type(&bare_fn.decl.output, f, use_absolute, cx)?;
|
||||
}
|
||||
} else if let Some(ty) = self.kind.as_blanket_ty() {
|
||||
if let Some(ty) = self.kind.as_blanket_ty() {
|
||||
fmt_type(ty, f, use_absolute, cx)?;
|
||||
} else {
|
||||
fmt_type(&self.for_, f, use_absolute, cx)?;
|
||||
self.print_type(&self.for_, f, use_absolute, cx)?;
|
||||
}
|
||||
|
||||
print_where_clause(&self.generics, cx, 0, Ending::Newline).fmt(f)
|
||||
})
|
||||
}
|
||||
fn print_type<'a, 'tcx: 'a>(
|
||||
&self,
|
||||
type_: &clean::Type,
|
||||
f: &mut fmt::Formatter<'_>,
|
||||
use_absolute: bool,
|
||||
cx: &'a Context<'tcx>,
|
||||
) -> Result<(), fmt::Error> {
|
||||
if let clean::Type::Tuple(types) = type_
|
||||
&& let [clean::Type::Generic(name)] = &types[..]
|
||||
&& (self.kind.is_fake_variadic() || self.kind.is_auto())
|
||||
{
|
||||
// Hardcoded anchor library/core/src/primitive_docs.rs
|
||||
// Link should match `# Trait implementations`
|
||||
primitive_link_fragment(
|
||||
f,
|
||||
PrimitiveType::Tuple,
|
||||
format_args!("({name}₁, {name}₂, …, {name}ₙ)"),
|
||||
"#trait-implementations-1",
|
||||
cx,
|
||||
)?;
|
||||
} else if let clean::Type::Array(ty, len) = type_
|
||||
&& let clean::Type::Generic(name) = &**ty
|
||||
&& &len[..] == "1"
|
||||
&& (self.kind.is_fake_variadic() || self.kind.is_auto())
|
||||
{
|
||||
primitive_link(f, PrimitiveType::Array, format_args!("[{name}; N]"), cx)?;
|
||||
} else if let clean::BareFunction(bare_fn) = &type_
|
||||
&& let [clean::Argument { type_: clean::Type::Generic(name), .. }] =
|
||||
&bare_fn.decl.inputs.values[..]
|
||||
&& (self.kind.is_fake_variadic() || self.kind.is_auto())
|
||||
{
|
||||
// Hardcoded anchor library/core/src/primitive_docs.rs
|
||||
// Link should match `# Trait implementations`
|
||||
|
||||
print_higher_ranked_params_with_space(&bare_fn.generic_params, cx).fmt(f)?;
|
||||
bare_fn.safety.print_with_space().fmt(f)?;
|
||||
print_abi_with_space(bare_fn.abi).fmt(f)?;
|
||||
let ellipsis = if bare_fn.decl.c_variadic { ", ..." } else { "" };
|
||||
primitive_link_fragment(
|
||||
f,
|
||||
PrimitiveType::Tuple,
|
||||
format_args!("fn({name}₁, {name}₂, …, {name}ₙ{ellipsis})"),
|
||||
"#trait-implementations-1",
|
||||
cx,
|
||||
)?;
|
||||
// Write output.
|
||||
if !bare_fn.decl.output.is_unit() {
|
||||
write!(f, " -> ")?;
|
||||
fmt_type(&bare_fn.decl.output, f, use_absolute, cx)?;
|
||||
}
|
||||
} else {
|
||||
fmt_type(&type_, f, use_absolute, cx)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl clean::Arguments {
|
||||
|
|
|
@ -16,3 +16,20 @@ pub trait Bar {}
|
|||
//@ has - '//section[@id="impl-Bar-for-(U,)"]/h3' 'impl<U: Foo> Bar for (U₁, U₂, …, Uₙ)'
|
||||
#[doc(fake_variadic)]
|
||||
impl<U: Foo> Bar for (U,) {}
|
||||
|
||||
pub trait Baz<T> { fn baz(&self) -> T { todo!() } }
|
||||
|
||||
//@ has foo/trait.Baz.html
|
||||
//@ has - '//section[@id="impl-Baz%3C(T,)%3E-for-%5BT;+1%5D"]/h3' 'impl<T> Baz<(T₁, T₂, …, Tₙ)> for [T; N]'
|
||||
#[doc(fake_variadic)]
|
||||
impl<T> Baz<(T,)> for [T; 1] {}
|
||||
|
||||
//@ has foo/trait.Baz.html
|
||||
//@ has - '//section[@id="impl-Baz%3C%5BT;+1%5D%3E-for-(T,)"]/h3' 'impl<T> Baz<[T; N]> for (T₁, T₂, …, Tₙ)'
|
||||
#[doc(fake_variadic)]
|
||||
impl<T> Baz<[T; 1]> for (T,) {}
|
||||
|
||||
//@ has foo/trait.Baz.html
|
||||
//@ has - '//section[@id="impl-Baz%3CT%3E-for-(T,)"]/h3' 'impl<T> Baz<T> for (T₁, T₂, …, Tₙ)'
|
||||
#[doc(fake_variadic)]
|
||||
impl<T> Baz<T> for (T,) {}
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
//@ check-pass
|
||||
|
||||
fn higher_ranked_fndef(ctx: &mut ()) {}
|
||||
|
||||
fn test(higher_ranked_fnptr: fn(&mut ())) {
|
||||
fn as_unsafe<T>(_: unsafe fn(T)) {}
|
||||
|
||||
// Make sure that we can cast higher-ranked fn items and pointers to
|
||||
// a non-higher-ranked target.
|
||||
as_unsafe(higher_ranked_fndef);
|
||||
as_unsafe(higher_ranked_fnptr);
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -1,6 +1,4 @@
|
|||
//@ run-pass
|
||||
#![feature(rustc_allow_const_fn_unstable)]
|
||||
|
||||
#![feature(rustc_attrs, staged_api)]
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
|
|
|
@ -28,9 +28,11 @@ const fn bar2() -> u32 { foo2() } //~ ERROR not yet stable as a const fn
|
|||
// conformity is required
|
||||
const fn bar3() -> u32 {
|
||||
let x = std::cell::Cell::new(0u32);
|
||||
x.get()
|
||||
x.get();
|
||||
//~^ ERROR const-stable function cannot use `#[feature(const_refs_to_cell)]`
|
||||
//~| ERROR cannot call non-const fn
|
||||
foo()
|
||||
//~^ ERROR is not yet stable as a const fn
|
||||
}
|
||||
|
||||
// check whether this function cannot be called even with the feature gate active
|
||||
|
|
|
@ -17,7 +17,7 @@ LL | const fn bar2() -> u32 { foo2() }
|
|||
error: const-stable function cannot use `#[feature(const_refs_to_cell)]`
|
||||
--> $DIR/min_const_fn_libstd_stability.rs:31:5
|
||||
|
|
||||
LL | x.get()
|
||||
LL | x.get();
|
||||
| ^
|
||||
|
|
||||
help: if it is not part of the public API, make this function unstably const
|
||||
|
@ -25,7 +25,7 @@ help: if it is not part of the public API, make this function unstably const
|
|||
LL + #[rustc_const_unstable(feature = "...", issue = "...")]
|
||||
LL | const fn bar3() -> u32 {
|
||||
|
|
||||
help: otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks
|
||||
help: otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks (but requires team approval)
|
||||
|
|
||||
LL + #[rustc_allow_const_fn_unstable(const_refs_to_cell)]
|
||||
LL | const fn bar3() -> u32 {
|
||||
|
@ -34,19 +34,27 @@ LL | const fn bar3() -> u32 {
|
|||
error[E0015]: cannot call non-const fn `Cell::<u32>::get` in constant functions
|
||||
--> $DIR/min_const_fn_libstd_stability.rs:31:7
|
||||
|
|
||||
LL | x.get()
|
||||
LL | x.get();
|
||||
| ^^^^^
|
||||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error: `foo` is not yet stable as a const fn
|
||||
--> $DIR/min_const_fn_libstd_stability.rs:34:5
|
||||
|
|
||||
LL | foo()
|
||||
| ^^^^^
|
||||
|
|
||||
= help: const-stable functions can only call other const-stable functions
|
||||
|
||||
error: `foo2_gated` is not yet stable as a const fn
|
||||
--> $DIR/min_const_fn_libstd_stability.rs:43:32
|
||||
--> $DIR/min_const_fn_libstd_stability.rs:45:32
|
||||
|
|
||||
LL | const fn bar2_gated() -> u32 { foo2_gated() }
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= help: const-stable functions can only call other const-stable functions
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0015`.
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
//@ edition: 2021
|
||||
|
||||
trait Trait {}
|
||||
|
||||
impl dyn Trait {
|
||||
const CONST: () = ();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
match () {
|
||||
Trait::CONST => {}
|
||||
//~^ ERROR trait objects must include the `dyn` keyword
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
error[E0782]: trait objects must include the `dyn` keyword
|
||||
--> $DIR/suggest-dyn-on-bare-trait-in-pat.rs:11:9
|
||||
|
|
||||
LL | Trait::CONST => {}
|
||||
| ^^^^^
|
||||
|
|
||||
help: add `dyn` keyword before this trait
|
||||
|
|
||||
LL | <dyn Trait>::CONST => {}
|
||||
| ++++ +
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0782`.
|
|
@ -9,7 +9,6 @@ use std::io::prelude::*;
|
|||
fn test1() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut _file = File::create("foo.txt")?;
|
||||
//~^ ERROR the `?` operator can only be used in a function
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -17,7 +16,6 @@ fn test2() -> Result<(), Box<dyn std::error::Error>> {
|
|||
let mut _file = File::create("foo.txt")?;
|
||||
//~^ ERROR the `?` operator can only be used in a function
|
||||
println!();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -27,9 +25,8 @@ macro_rules! mac {
|
|||
let mut _file = File::create("foo.txt")?;
|
||||
//~^ ERROR the `?` operator can only be used in a function
|
||||
println!();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -39,23 +36,20 @@ impl A {
|
|||
fn test4(&self) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut _file = File::create("foo.txt")?;
|
||||
//~^ ERROR the `?` operator can only be used in a method
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn test5(&self) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut _file = File::create("foo.txt")?;
|
||||
//~^ ERROR the `?` operator can only be used in a method
|
||||
println!();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut _file = File::create("foo.txt")?;
|
||||
//~^ ERROR the `?` operator can only be used in a function
|
||||
mac!();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -12,9 +12,7 @@ help: consider adding return type
|
|||
LL ~ fn test1() -> Result<(), Box<dyn std::error::Error>> {
|
||||
LL | let mut _file = File::create("foo.txt")?;
|
||||
LL |
|
||||
LL +
|
||||
LL + Ok(())
|
||||
LL + }
|
||||
|
|
||||
|
||||
error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
|
||||
|
@ -32,9 +30,7 @@ LL ~ fn test2() -> Result<(), Box<dyn std::error::Error>> {
|
|||
LL | let mut _file = File::create("foo.txt")?;
|
||||
LL |
|
||||
LL | println!();
|
||||
LL +
|
||||
LL + Ok(())
|
||||
LL + }
|
||||
|
|
||||
|
||||
error[E0277]: the `?` operator can only be used in a method that returns `Result` or `Option` (or another type that implements `FromResidual`)
|
||||
|
@ -51,9 +47,8 @@ help: consider adding return type
|
|||
LL ~ fn test4(&self) -> Result<(), Box<dyn std::error::Error>> {
|
||||
LL | let mut _file = File::create("foo.txt")?;
|
||||
LL |
|
||||
LL ~
|
||||
LL + Ok(())
|
||||
LL + }
|
||||
LL ~ Ok(())
|
||||
LL ~ }
|
||||
|
|
||||
|
||||
error[E0277]: the `?` operator can only be used in a method that returns `Result` or `Option` (or another type that implements `FromResidual`)
|
||||
|
@ -71,9 +66,8 @@ LL ~ fn test5(&self) -> Result<(), Box<dyn std::error::Error>> {
|
|||
LL | let mut _file = File::create("foo.txt")?;
|
||||
LL |
|
||||
LL | println!();
|
||||
LL ~
|
||||
LL + Ok(())
|
||||
LL + }
|
||||
LL ~ Ok(())
|
||||
LL ~ }
|
||||
|
|
||||
|
||||
error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
|
||||
|
@ -91,9 +85,7 @@ LL ~ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
LL | let mut _file = File::create("foo.txt")?;
|
||||
LL |
|
||||
LL | mac!();
|
||||
LL +
|
||||
LL + Ok(())
|
||||
LL + }
|
||||
|
|
||||
|
||||
error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
|
||||
|
@ -115,9 +107,8 @@ LL ~ fn test3() -> Result<(), Box<dyn std::error::Error>> {
|
|||
LL | let mut _file = File::create("foo.txt")?;
|
||||
LL |
|
||||
LL | println!();
|
||||
LL ~
|
||||
LL + Ok(())
|
||||
LL + }
|
||||
LL ~ Ok(())
|
||||
LL ~ }
|
||||
|
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
|
|
@ -14,9 +14,7 @@ LL ~ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
LL | // error for a `Try` type on a non-`Try` fn
|
||||
...
|
||||
LL | try_trait_generic::<()>();
|
||||
LL +
|
||||
LL + Ok(())
|
||||
LL + }
|
||||
|
|
||||
|
||||
error[E0277]: the `?` operator can only be applied to values that implement `Try`
|
||||
|
|
Loading…
Reference in New Issue