Auto merge of #106215 - matthiaskrgr:rollup-53r89ww, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #106028 (docs/test: add UI test and long-form error docs for `E0461`) - #106172 (Suggest `impl Iterator` when possible for `_` return type) - #106173 (Deduplicate `op` methods) - #106176 (Recover `fn` keyword as `Fn` trait in bounds) - #106194 (rustdoc: combine common sidebar background color CSS rules) - #106199 (Silence knock-down errors on `[type error]` bindings) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
270c94e484
@ -244,6 +244,7 @@ E0457: include_str!("./error_codes/E0457.md"),
|
||||
E0458: include_str!("./error_codes/E0458.md"),
|
||||
E0459: include_str!("./error_codes/E0459.md"),
|
||||
E0460: include_str!("./error_codes/E0460.md"),
|
||||
E0461: include_str!("./error_codes/E0461.md"),
|
||||
E0462: include_str!("./error_codes/E0462.md"),
|
||||
E0463: include_str!("./error_codes/E0463.md"),
|
||||
E0464: include_str!("./error_codes/E0464.md"),
|
||||
@ -595,7 +596,6 @@ E0791: include_str!("./error_codes/E0791.md"),
|
||||
// E0421, // merged into 531
|
||||
// E0427, // merged into 530
|
||||
// E0456, // plugin `..` is not available for triple `..`
|
||||
E0461, // couldn't find crate `..` with expected target triple ..
|
||||
E0465, // multiple .. candidates for `..` found
|
||||
// E0467, // removed
|
||||
// E0470, // removed
|
||||
|
30
compiler/rustc_error_codes/src/error_codes/E0461.md
Normal file
30
compiler/rustc_error_codes/src/error_codes/E0461.md
Normal file
@ -0,0 +1,30 @@
|
||||
Couldn't find crate `..` with expected target triple `..`.
|
||||
|
||||
Example of erroneous code:
|
||||
|
||||
`a.rs`
|
||||
```ignore (cannot-link-with-other-tests)
|
||||
#![crate_type = "lib"]
|
||||
|
||||
fn foo() {}
|
||||
```
|
||||
|
||||
`main.rs`
|
||||
```ignore (cannot-link-with-other-tests)
|
||||
extern crate a;
|
||||
|
||||
fn main() {
|
||||
a::foo();
|
||||
}
|
||||
```
|
||||
|
||||
`a.rs` is then compiled with `--target powerpc-unknown-linux-gnu` and `b.rs`
|
||||
with `--target x86_64-unknown-linux-gnu`. `a.rs` is compiled into a binary
|
||||
format incompatible with `b.rs`; PowerPC and x86 are totally different
|
||||
architectures. This issue also extends to any difference in target triples, as
|
||||
`std` is operating-system specific.
|
||||
|
||||
This error can be fixed by:
|
||||
* Using [Cargo](../cargo/index.html), the Rust package manager, automatically
|
||||
fixing this issue.
|
||||
* Recompiling either crate so that they target a consistent target triple.
|
@ -365,3 +365,6 @@ parse_invalid_identifier_with_leading_number = expected identifier, found number
|
||||
|
||||
parse_maybe_fn_typo_with_impl = you might have meant to write `impl` instead of `fn`
|
||||
.suggestion = replace `fn` with `impl` here
|
||||
|
||||
parse_expected_fn_path_found_fn_keyword = expected identifier, found keyword `fn`
|
||||
.suggestion = use `Fn` to refer to the trait
|
||||
|
@ -626,7 +626,7 @@ impl<'a> ExtCtxt<'a> {
|
||||
|
||||
// Builds `#[name = val]`.
|
||||
//
|
||||
// Note: `span` is used for both the identifer and the value.
|
||||
// Note: `span` is used for both the identifier and the value.
|
||||
pub fn attr_name_value_str(&self, name: Symbol, val: Symbol, span: Span) -> ast::Attribute {
|
||||
let g = &self.sess.parse_sess.attr_id_generator;
|
||||
attr::mk_attr_name_value_str(g, ast::AttrStyle::Outer, name, val, span)
|
||||
|
@ -24,6 +24,8 @@ use rustc_hir as hir;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::intravisit::{self, Visitor};
|
||||
use rustc_hir::{GenericParamKind, Node};
|
||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_middle::hir::nested_filter;
|
||||
use rustc_middle::ty::query::Providers;
|
||||
use rustc_middle::ty::util::{Discr, IntTypeExt};
|
||||
@ -31,7 +33,9 @@ use rustc_middle::ty::{self, AdtKind, Const, IsSuggestable, ToPredicate, Ty, TyC
|
||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
use rustc_span::Span;
|
||||
use rustc_target::spec::abi;
|
||||
use rustc_trait_selection::infer::InferCtxtExt;
|
||||
use rustc_trait_selection::traits::error_reporting::suggestions::NextTypeParamName;
|
||||
use rustc_trait_selection::traits::ObligationCtxt;
|
||||
use std::iter;
|
||||
|
||||
mod generics_of;
|
||||
@ -1224,7 +1228,17 @@ fn infer_return_ty_for_fn_sig<'tcx>(
|
||||
// to prevent the user from getting a papercut while trying to use the unique closure
|
||||
// syntax (e.g. `[closure@src/lib.rs:2:5: 2:9]`).
|
||||
diag.help("consider using an `Fn`, `FnMut`, or `FnOnce` trait bound");
|
||||
diag.note("for more information on `Fn` traits and closure types, see https://doc.rust-lang.org/book/ch13-01-closures.html");
|
||||
diag.note(
|
||||
"for more information on `Fn` traits and closure types, see \
|
||||
https://doc.rust-lang.org/book/ch13-01-closures.html",
|
||||
);
|
||||
} else if let Some(i_ty) = suggest_impl_iterator(tcx, ret_ty, ty.span, hir_id, def_id) {
|
||||
diag.span_suggestion(
|
||||
ty.span,
|
||||
"replace with an appropriate return type",
|
||||
format!("impl Iterator<Item = {}>", i_ty),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
diag.emit();
|
||||
|
||||
@ -1242,6 +1256,51 @@ fn infer_return_ty_for_fn_sig<'tcx>(
|
||||
}
|
||||
}
|
||||
|
||||
fn suggest_impl_iterator<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
ret_ty: Ty<'tcx>,
|
||||
span: Span,
|
||||
hir_id: hir::HirId,
|
||||
def_id: LocalDefId,
|
||||
) -> Option<Ty<'tcx>> {
|
||||
let Some(iter_trait) = tcx.get_diagnostic_item(sym::Iterator) else { return None; };
|
||||
let Some(iterator_item) = tcx.get_diagnostic_item(sym::IteratorItem) else { return None; };
|
||||
if !tcx
|
||||
.infer_ctxt()
|
||||
.build()
|
||||
.type_implements_trait(iter_trait, [ret_ty], tcx.param_env(def_id))
|
||||
.must_apply_modulo_regions()
|
||||
{
|
||||
return None;
|
||||
}
|
||||
let infcx = tcx.infer_ctxt().build();
|
||||
let ocx = ObligationCtxt::new_in_snapshot(&infcx);
|
||||
// Find the type of `Iterator::Item`.
|
||||
let origin = TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span };
|
||||
let ty_var = infcx.next_ty_var(origin);
|
||||
let projection = ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::Projection(
|
||||
ty::ProjectionPredicate {
|
||||
projection_ty: tcx.mk_alias_ty(iterator_item, tcx.mk_substs([ret_ty.into()].iter())),
|
||||
term: ty_var.into(),
|
||||
},
|
||||
)));
|
||||
// Add `<ret_ty as Iterator>::Item = _` obligation.
|
||||
ocx.register_obligation(crate::traits::Obligation::misc(
|
||||
tcx,
|
||||
span,
|
||||
hir_id,
|
||||
tcx.param_env(def_id),
|
||||
projection,
|
||||
));
|
||||
if ocx.select_where_possible().is_empty()
|
||||
&& let item_ty = infcx.resolve_vars_if_possible(ty_var)
|
||||
&& item_ty.is_suggestable(tcx, false)
|
||||
{
|
||||
return Some(item_ty);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn impl_trait_ref(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::TraitRef<'_>> {
|
||||
let icx = ItemCtxt::new(tcx, def_id);
|
||||
let item = tcx.hir().expect_item(def_id.expect_local());
|
||||
|
@ -5,6 +5,7 @@ use rustc_hir::intravisit;
|
||||
use rustc_hir::intravisit::Visitor;
|
||||
use rustc_hir::{HirId, Node};
|
||||
use rustc_middle::hir::nested_filter;
|
||||
use rustc_middle::ty::print::with_forced_trimmed_paths;
|
||||
use rustc_middle::ty::subst::InternalSubsts;
|
||||
use rustc_middle::ty::util::IntTypeExt;
|
||||
use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt, TypeFolder, TypeSuperFoldable, TypeVisitable};
|
||||
@ -907,10 +908,10 @@ fn infer_placeholder_type<'a>(
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
} else {
|
||||
err.span_note(
|
||||
with_forced_trimmed_paths!(err.span_note(
|
||||
tcx.hir().body(body_id).value.span,
|
||||
&format!("however, the inferred type `{}` cannot be named", ty),
|
||||
);
|
||||
&format!("however, the inferred type `{ty}` cannot be named"),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@ -931,10 +932,10 @@ fn infer_placeholder_type<'a>(
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
} else {
|
||||
diag.span_note(
|
||||
with_forced_trimmed_paths!(diag.span_note(
|
||||
tcx.hir().body(body_id).value.span,
|
||||
&format!("however, the inferred type `{}` cannot be named", ty),
|
||||
);
|
||||
&format!("however, the inferred type `{ty}` cannot be named"),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -241,7 +241,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
});
|
||||
|
||||
if let Some(ok) = self.lookup_method_in_trait(
|
||||
call_expr.span,
|
||||
self.misc(call_expr.span),
|
||||
method_name,
|
||||
trait_def_id,
|
||||
adjusted_ty,
|
||||
|
@ -1307,7 +1307,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// Type check the initializer.
|
||||
if let Some(ref init) = decl.init {
|
||||
let init_ty = self.check_decl_initializer(decl.hir_id, decl.pat, &init);
|
||||
self.overwrite_local_ty_if_err(decl.hir_id, decl.pat, decl_ty, init_ty);
|
||||
self.overwrite_local_ty_if_err(decl.hir_id, decl.pat, init_ty);
|
||||
}
|
||||
|
||||
// Does the expected pattern type originate from an expression and what is the span?
|
||||
@ -1322,7 +1322,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// Type check the pattern. Override if necessary to avoid knock-on errors.
|
||||
self.check_pat_top(&decl.pat, decl_ty, ty_span, origin_expr);
|
||||
let pat_ty = self.node_ty(decl.pat.hir_id);
|
||||
self.overwrite_local_ty_if_err(decl.hir_id, decl.pat, decl_ty, pat_ty);
|
||||
self.overwrite_local_ty_if_err(decl.hir_id, decl.pat, pat_ty);
|
||||
|
||||
if let Some(blk) = decl.els {
|
||||
let previous_diverges = self.diverges.get();
|
||||
@ -1627,14 +1627,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
&self,
|
||||
hir_id: hir::HirId,
|
||||
pat: &'tcx hir::Pat<'tcx>,
|
||||
decl_ty: Ty<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) {
|
||||
if ty.references_error() {
|
||||
// Override the types everywhere with `err()` to avoid knock on errors.
|
||||
self.write_ty(hir_id, ty);
|
||||
self.write_ty(pat.hir_id, ty);
|
||||
let local_ty = LocalTy { decl_ty, revealed_ty: ty };
|
||||
let err = self.tcx.ty_error();
|
||||
self.write_ty(hir_id, err);
|
||||
self.write_ty(pat.hir_id, err);
|
||||
let local_ty = LocalTy { decl_ty: err, revealed_ty: err };
|
||||
self.locals.borrow_mut().insert(hir_id, local_ty);
|
||||
self.locals.borrow_mut().insert(pat.hir_id, local_ty);
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ pub use self::suggest::SelfSource;
|
||||
pub use self::MethodError::*;
|
||||
|
||||
use crate::errors::OpMethodGenericParams;
|
||||
use crate::{Expectation, FnCtxt};
|
||||
use crate::FnCtxt;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_errors::{Applicability, Diagnostic};
|
||||
use rustc_hir as hir;
|
||||
@ -264,7 +264,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
pub(super) fn obligation_for_method(
|
||||
&self,
|
||||
span: Span,
|
||||
cause: ObligationCause<'tcx>,
|
||||
trait_def_id: DefId,
|
||||
self_ty: Ty<'tcx>,
|
||||
opt_input_types: Option<&[Ty<'tcx>]>,
|
||||
@ -282,71 +282,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
self.var_for_def(span, param)
|
||||
self.var_for_def(cause.span, param)
|
||||
});
|
||||
|
||||
let trait_ref = self.tcx.mk_trait_ref(trait_def_id, substs);
|
||||
|
||||
// Construct an obligation
|
||||
let poly_trait_ref = ty::Binder::dummy(trait_ref);
|
||||
(
|
||||
traits::Obligation::misc(
|
||||
self.tcx,
|
||||
span,
|
||||
self.body_id,
|
||||
self.param_env,
|
||||
poly_trait_ref.without_const(),
|
||||
),
|
||||
substs,
|
||||
)
|
||||
}
|
||||
|
||||
pub(super) fn obligation_for_op_method(
|
||||
&self,
|
||||
span: Span,
|
||||
trait_def_id: DefId,
|
||||
self_ty: Ty<'tcx>,
|
||||
opt_input_type: Option<Ty<'tcx>>,
|
||||
opt_input_expr: Option<&'tcx hir::Expr<'tcx>>,
|
||||
expected: Expectation<'tcx>,
|
||||
) -> (traits::Obligation<'tcx, ty::Predicate<'tcx>>, &'tcx ty::List<ty::subst::GenericArg<'tcx>>)
|
||||
{
|
||||
// Construct a trait-reference `self_ty : Trait<input_tys>`
|
||||
let substs = InternalSubsts::for_item(self.tcx, trait_def_id, |param, _| {
|
||||
match param.kind {
|
||||
GenericParamDefKind::Lifetime | GenericParamDefKind::Const { .. } => {}
|
||||
GenericParamDefKind::Type { .. } => {
|
||||
if param.index == 0 {
|
||||
return self_ty.into();
|
||||
} else if let Some(input_type) = opt_input_type {
|
||||
return input_type.into();
|
||||
}
|
||||
}
|
||||
}
|
||||
self.var_for_def(span, param)
|
||||
});
|
||||
|
||||
let trait_ref = self.tcx.mk_trait_ref(trait_def_id, substs);
|
||||
|
||||
// Construct an obligation
|
||||
let poly_trait_ref = ty::Binder::dummy(trait_ref);
|
||||
let output_ty = expected.only_has_type(self).and_then(|ty| (!ty.needs_infer()).then(|| ty));
|
||||
|
||||
(
|
||||
traits::Obligation::new(
|
||||
self.tcx,
|
||||
traits::ObligationCause::new(
|
||||
span,
|
||||
self.body_id,
|
||||
traits::BinOp {
|
||||
rhs_span: opt_input_expr.map(|expr| expr.span),
|
||||
is_lit: opt_input_expr
|
||||
.map_or(false, |expr| matches!(expr.kind, hir::ExprKind::Lit(_))),
|
||||
output_ty,
|
||||
},
|
||||
),
|
||||
cause,
|
||||
self.param_env,
|
||||
poly_trait_ref,
|
||||
poly_trait_ref.without_const(),
|
||||
),
|
||||
substs,
|
||||
)
|
||||
@ -357,55 +305,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
/// In particular, it doesn't really do any probing: it simply constructs
|
||||
/// an obligation for a particular trait with the given self type and checks
|
||||
/// whether that trait is implemented.
|
||||
#[instrument(level = "debug", skip(self, span))]
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
pub(super) fn lookup_method_in_trait(
|
||||
&self,
|
||||
span: Span,
|
||||
cause: ObligationCause<'tcx>,
|
||||
m_name: Ident,
|
||||
trait_def_id: DefId,
|
||||
self_ty: Ty<'tcx>,
|
||||
opt_input_types: Option<&[Ty<'tcx>]>,
|
||||
) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
|
||||
let (obligation, substs) =
|
||||
self.obligation_for_method(span, trait_def_id, self_ty, opt_input_types);
|
||||
self.construct_obligation_for_trait(
|
||||
span,
|
||||
m_name,
|
||||
trait_def_id,
|
||||
obligation,
|
||||
substs,
|
||||
None,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
pub(super) fn lookup_op_method_in_trait(
|
||||
&self,
|
||||
span: Span,
|
||||
m_name: Ident,
|
||||
trait_def_id: DefId,
|
||||
self_ty: Ty<'tcx>,
|
||||
opt_input_type: Option<Ty<'tcx>>,
|
||||
opt_input_expr: Option<&'tcx hir::Expr<'tcx>>,
|
||||
expected: Expectation<'tcx>,
|
||||
) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
|
||||
let (obligation, substs) = self.obligation_for_op_method(
|
||||
span,
|
||||
trait_def_id,
|
||||
self_ty,
|
||||
opt_input_type,
|
||||
opt_input_expr,
|
||||
expected,
|
||||
);
|
||||
self.construct_obligation_for_trait(
|
||||
span,
|
||||
m_name,
|
||||
trait_def_id,
|
||||
obligation,
|
||||
substs,
|
||||
opt_input_expr,
|
||||
true,
|
||||
)
|
||||
self.obligation_for_method(cause, trait_def_id, self_ty, opt_input_types);
|
||||
self.construct_obligation_for_trait(m_name, trait_def_id, obligation, substs)
|
||||
}
|
||||
|
||||
// FIXME(#18741): it seems likely that we can consolidate some of this
|
||||
@ -413,13 +324,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// of this method is basically the same as confirmation.
|
||||
fn construct_obligation_for_trait(
|
||||
&self,
|
||||
span: Span,
|
||||
m_name: Ident,
|
||||
trait_def_id: DefId,
|
||||
obligation: traits::PredicateObligation<'tcx>,
|
||||
substs: &'tcx ty::List<ty::subst::GenericArg<'tcx>>,
|
||||
opt_input_expr: Option<&'tcx hir::Expr<'tcx>>,
|
||||
is_op: bool,
|
||||
) -> Option<InferOk<'tcx, MethodCallee<'tcx>>> {
|
||||
debug!(?obligation);
|
||||
|
||||
@ -435,7 +343,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let tcx = self.tcx;
|
||||
let Some(method_item) = self.associated_value(trait_def_id, m_name) else {
|
||||
tcx.sess.delay_span_bug(
|
||||
span,
|
||||
obligation.cause.span,
|
||||
"operator trait does not have corresponding operator method",
|
||||
);
|
||||
return None;
|
||||
@ -461,24 +369,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// with bound regions.
|
||||
let fn_sig = tcx.bound_fn_sig(def_id);
|
||||
let fn_sig = fn_sig.subst(self.tcx, substs);
|
||||
let fn_sig = self.replace_bound_vars_with_fresh_vars(span, infer::FnCall, fn_sig);
|
||||
let fn_sig =
|
||||
self.replace_bound_vars_with_fresh_vars(obligation.cause.span, infer::FnCall, fn_sig);
|
||||
|
||||
let cause = if is_op {
|
||||
ObligationCause::new(
|
||||
span,
|
||||
self.body_id,
|
||||
traits::BinOp {
|
||||
rhs_span: opt_input_expr.map(|expr| expr.span),
|
||||
is_lit: opt_input_expr
|
||||
.map_or(false, |expr| matches!(expr.kind, hir::ExprKind::Lit(_))),
|
||||
output_ty: None,
|
||||
},
|
||||
)
|
||||
} else {
|
||||
traits::ObligationCause::misc(span, self.body_id)
|
||||
};
|
||||
|
||||
let InferOk { value, obligations: o } = self.at(&cause, self.param_env).normalize(fn_sig);
|
||||
let InferOk { value, obligations: o } =
|
||||
self.at(&obligation.cause, self.param_env).normalize(fn_sig);
|
||||
let fn_sig = {
|
||||
obligations.extend(o);
|
||||
value
|
||||
@ -494,7 +389,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// any late-bound regions appearing in its bounds.
|
||||
let bounds = self.tcx.predicates_of(def_id).instantiate(self.tcx, substs);
|
||||
|
||||
let InferOk { value, obligations: o } = self.at(&cause, self.param_env).normalize(bounds);
|
||||
let InferOk { value, obligations: o } =
|
||||
self.at(&obligation.cause, self.param_env).normalize(bounds);
|
||||
let bounds = {
|
||||
obligations.extend(o);
|
||||
value
|
||||
@ -502,7 +398,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
assert!(!bounds.has_escaping_bound_vars());
|
||||
|
||||
let predicates_cause = cause.clone();
|
||||
let predicates_cause = obligation.cause.clone();
|
||||
obligations.extend(traits::predicates_for_generics(
|
||||
move |_, _| predicates_cause.clone(),
|
||||
self.param_env,
|
||||
@ -517,7 +413,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
);
|
||||
obligations.push(traits::Obligation::new(
|
||||
tcx,
|
||||
cause,
|
||||
obligation.cause,
|
||||
self.param_env,
|
||||
ty::Binder::dummy(ty::PredicateKind::WellFormed(method_ty.into())),
|
||||
));
|
||||
|
@ -12,14 +12,16 @@ use rustc_middle::ty::adjustment::{
|
||||
Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability,
|
||||
};
|
||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||
use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt, TypeFolder, TypeSuperFoldable, TypeVisitable};
|
||||
use rustc_middle::ty::{
|
||||
self, DefIdTree, IsSuggestable, Ty, TyCtxt, TypeFolder, TypeSuperFoldable, TypeVisitable,
|
||||
};
|
||||
use rustc_session::errors::ExprParenthesesNeeded;
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::symbol::{sym, Ident};
|
||||
use rustc_span::Span;
|
||||
use rustc_trait_selection::infer::InferCtxtExt;
|
||||
use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt as _;
|
||||
use rustc_trait_selection::traits::FulfillmentError;
|
||||
use rustc_trait_selection::traits::{self, FulfillmentError};
|
||||
use rustc_type_ir::sty::TyKind::*;
|
||||
|
||||
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
@ -48,8 +50,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
if self
|
||||
.lookup_op_method(
|
||||
lhs_deref_ty,
|
||||
Some(rhs_ty),
|
||||
Some(rhs),
|
||||
Some((rhs, rhs_ty)),
|
||||
Op::Binary(op, IsAssign::Yes),
|
||||
expected,
|
||||
)
|
||||
@ -60,8 +61,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
if self
|
||||
.lookup_op_method(
|
||||
lhs_ty,
|
||||
Some(rhs_ty),
|
||||
Some(rhs),
|
||||
Some((rhs, rhs_ty)),
|
||||
Op::Binary(op, IsAssign::Yes),
|
||||
expected,
|
||||
)
|
||||
@ -248,8 +248,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
let result = self.lookup_op_method(
|
||||
lhs_ty,
|
||||
Some(rhs_ty_var),
|
||||
Some(rhs_expr),
|
||||
Some((rhs_expr, rhs_ty_var)),
|
||||
Op::Binary(op, is_assign),
|
||||
expected,
|
||||
);
|
||||
@ -382,8 +381,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
if self
|
||||
.lookup_op_method(
|
||||
lhs_deref_ty,
|
||||
Some(rhs_ty),
|
||||
Some(rhs_expr),
|
||||
Some((rhs_expr, rhs_ty)),
|
||||
Op::Binary(op, is_assign),
|
||||
expected,
|
||||
)
|
||||
@ -410,8 +408,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let is_compatible = |lhs_ty, rhs_ty| {
|
||||
self.lookup_op_method(
|
||||
lhs_ty,
|
||||
Some(rhs_ty),
|
||||
Some(rhs_expr),
|
||||
Some((rhs_expr, rhs_ty)),
|
||||
Op::Binary(op, is_assign),
|
||||
expected,
|
||||
)
|
||||
@ -471,8 +468,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let errors = self
|
||||
.lookup_op_method(
|
||||
lhs_ty,
|
||||
Some(rhs_ty),
|
||||
Some(rhs_expr),
|
||||
Some((rhs_expr, rhs_ty)),
|
||||
Op::Binary(op, is_assign),
|
||||
expected,
|
||||
)
|
||||
@ -492,6 +488,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
if let Some(output_def_id) = output_def_id
|
||||
&& let Some(trait_def_id) = trait_def_id
|
||||
&& self.tcx.parent(output_def_id) == trait_def_id
|
||||
&& output_ty.is_suggestable(self.tcx, false)
|
||||
{
|
||||
Some(("Output", *output_ty))
|
||||
} else {
|
||||
@ -625,7 +622,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
expected: Expectation<'tcx>,
|
||||
) -> Ty<'tcx> {
|
||||
assert!(op.is_by_value());
|
||||
match self.lookup_op_method(operand_ty, None, None, Op::Unary(op, ex.span), expected) {
|
||||
match self.lookup_op_method(operand_ty, None, Op::Unary(op, ex.span), expected) {
|
||||
Ok(method) => {
|
||||
self.write_method_call(ex.hir_id, method);
|
||||
method.sig.output()
|
||||
@ -712,8 +709,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
fn lookup_op_method(
|
||||
&self,
|
||||
lhs_ty: Ty<'tcx>,
|
||||
other_ty: Option<Ty<'tcx>>,
|
||||
other_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
|
||||
opt_rhs: Option<(&'tcx hir::Expr<'tcx>, Ty<'tcx>)>,
|
||||
op: Op,
|
||||
expected: Expectation<'tcx>,
|
||||
) -> Result<MethodCallee<'tcx>, Vec<FulfillmentError<'tcx>>> {
|
||||
@ -742,20 +738,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
Op::Unary(..) => 0,
|
||||
},
|
||||
) {
|
||||
self.tcx
|
||||
.sess
|
||||
.delay_span_bug(span, "operator didn't have the right number of generic args");
|
||||
return Err(vec![]);
|
||||
}
|
||||
|
||||
let opname = Ident::with_dummy_span(opname);
|
||||
let input_types =
|
||||
opt_rhs.as_ref().map(|(_, ty)| std::slice::from_ref(ty)).unwrap_or_default();
|
||||
let cause = self.cause(
|
||||
span,
|
||||
traits::BinOp {
|
||||
rhs_span: opt_rhs.map(|(expr, _)| expr.span),
|
||||
is_lit: opt_rhs
|
||||
.map_or(false, |(expr, _)| matches!(expr.kind, hir::ExprKind::Lit(_))),
|
||||
output_ty: expected.only_has_type(self),
|
||||
},
|
||||
);
|
||||
|
||||
let method = trait_did.and_then(|trait_did| {
|
||||
self.lookup_op_method_in_trait(
|
||||
span,
|
||||
opname,
|
||||
trait_did,
|
||||
lhs_ty,
|
||||
other_ty,
|
||||
other_ty_expr,
|
||||
expected,
|
||||
)
|
||||
self.lookup_method_in_trait(cause.clone(), opname, trait_did, lhs_ty, Some(input_types))
|
||||
});
|
||||
|
||||
match (method, trait_did) {
|
||||
@ -766,14 +769,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
(None, None) => Err(vec![]),
|
||||
(None, Some(trait_did)) => {
|
||||
let (obligation, _) = self.obligation_for_op_method(
|
||||
span,
|
||||
trait_did,
|
||||
lhs_ty,
|
||||
other_ty,
|
||||
other_ty_expr,
|
||||
expected,
|
||||
);
|
||||
let (obligation, _) =
|
||||
self.obligation_for_method(cause, trait_did, lhs_ty, Some(input_types));
|
||||
Err(rustc_trait_selection::traits::fully_solve_obligation(self, obligation))
|
||||
}
|
||||
}
|
||||
|
@ -225,7 +225,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
imm_tr.and_then(|trait_did| {
|
||||
self.lookup_method_in_trait(
|
||||
span,
|
||||
self.misc(span),
|
||||
Ident::with_dummy_span(imm_op),
|
||||
trait_did,
|
||||
base_ty,
|
||||
@ -264,7 +264,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
mut_tr.and_then(|trait_did| {
|
||||
self.lookup_method_in_trait(
|
||||
span,
|
||||
self.misc(span),
|
||||
Ident::with_dummy_span(mut_op),
|
||||
trait_did,
|
||||
base_ty,
|
||||
|
@ -851,7 +851,7 @@ impl Cursor<'_> {
|
||||
}
|
||||
|
||||
// Eats the identifier. Note: succeeds on `_`, which isn't a valid
|
||||
// identifer.
|
||||
// identifier.
|
||||
fn eat_identifier(&mut self) {
|
||||
if !is_id_start(self.first()) {
|
||||
return;
|
||||
|
@ -1229,3 +1229,11 @@ pub(crate) struct FnTypoWithImpl {
|
||||
#[suggestion(applicability = "maybe-incorrect", code = "impl", style = "verbose")]
|
||||
pub fn_span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_expected_fn_path_found_fn_keyword)]
|
||||
pub(crate) struct ExpectedFnPathFoundFnKeyword {
|
||||
#[primary_span]
|
||||
#[suggestion(applicability = "machine-applicable", code = "Fn", style = "verbose")]
|
||||
pub fn_token_span: Span,
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
use super::{Parser, PathStyle, TokenType};
|
||||
|
||||
use crate::errors::{FnPtrWithGenerics, FnPtrWithGenericsSugg};
|
||||
use crate::errors::{ExpectedFnPathFoundFnKeyword, FnPtrWithGenerics, FnPtrWithGenericsSugg};
|
||||
use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
|
||||
|
||||
use ast::DUMMY_NODE_ID;
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::token::{self, Delimiter, Token, TokenKind};
|
||||
use rustc_ast::util::case::Case;
|
||||
@ -12,7 +13,9 @@ use rustc_ast::{
|
||||
};
|
||||
use rustc_errors::{pluralize, struct_span_err, Applicability, PResult};
|
||||
use rustc_span::source_map::Span;
|
||||
use rustc_span::symbol::{kw, sym};
|
||||
use rustc_span::symbol::{kw, sym, Ident};
|
||||
use rustc_span::Symbol;
|
||||
use thin_vec::thin_vec;
|
||||
|
||||
/// Any `?` or `~const` modifiers that appear at the start of a bound.
|
||||
struct BoundModifiers {
|
||||
@ -931,7 +934,14 @@ impl<'a> Parser<'a> {
|
||||
modifiers: BoundModifiers,
|
||||
) -> PResult<'a, GenericBound> {
|
||||
let lifetime_defs = self.parse_late_bound_lifetime_defs()?;
|
||||
let path = self.parse_path(PathStyle::Type)?;
|
||||
let path = if self.token.is_keyword(kw::Fn)
|
||||
&& self.look_ahead(1, |tok| tok.kind == TokenKind::OpenDelim(Delimiter::Parenthesis))
|
||||
&& let Some(path) = self.recover_path_from_fn()
|
||||
{
|
||||
path
|
||||
} else {
|
||||
self.parse_path(PathStyle::Type)?
|
||||
};
|
||||
if has_parens {
|
||||
if self.token.is_like_plus() {
|
||||
// Someone has written something like `&dyn (Trait + Other)`. The correct code
|
||||
@ -960,6 +970,38 @@ impl<'a> Parser<'a> {
|
||||
Ok(GenericBound::Trait(poly_trait, modifier))
|
||||
}
|
||||
|
||||
// recovers a `Fn(..)` parenthesized-style path from `fn(..)`
|
||||
fn recover_path_from_fn(&mut self) -> Option<ast::Path> {
|
||||
let fn_token_span = self.token.span;
|
||||
self.bump();
|
||||
let args_lo = self.token.span;
|
||||
let snapshot = self.create_snapshot_for_diagnostic();
|
||||
match self.parse_fn_decl(|_| false, AllowPlus::No, RecoverReturnSign::OnlyFatArrow) {
|
||||
Ok(decl) => {
|
||||
self.sess.emit_err(ExpectedFnPathFoundFnKeyword { fn_token_span });
|
||||
Some(ast::Path {
|
||||
span: fn_token_span.to(self.prev_token.span),
|
||||
segments: thin_vec![ast::PathSegment {
|
||||
ident: Ident::new(Symbol::intern("Fn"), fn_token_span),
|
||||
id: DUMMY_NODE_ID,
|
||||
args: Some(P(ast::GenericArgs::Parenthesized(ast::ParenthesizedArgs {
|
||||
span: args_lo.to(self.prev_token.span),
|
||||
inputs: decl.inputs.iter().map(|a| a.ty.clone()).collect(),
|
||||
inputs_span: args_lo.until(decl.output.span()),
|
||||
output: decl.output.clone(),
|
||||
}))),
|
||||
}],
|
||||
tokens: None,
|
||||
})
|
||||
}
|
||||
Err(diag) => {
|
||||
diag.cancel();
|
||||
self.restore_snapshot(snapshot);
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Optionally parses `for<$generic_params>`.
|
||||
pub(super) fn parse_late_bound_lifetime_defs(&mut self) -> PResult<'a, Vec<GenericParam>> {
|
||||
if self.eat_keyword(kw::For) {
|
||||
|
@ -213,6 +213,7 @@ symbols! {
|
||||
Is,
|
||||
ItemContext,
|
||||
Iterator,
|
||||
IteratorItem,
|
||||
Layout,
|
||||
Left,
|
||||
LinkedList,
|
||||
|
@ -66,6 +66,7 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {}
|
||||
#[must_use = "iterators are lazy and do nothing unless consumed"]
|
||||
pub trait Iterator {
|
||||
/// The type of the elements being iterated over.
|
||||
#[rustc_diagnostic_item = "IteratorItem"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
type Item;
|
||||
|
||||
|
@ -378,10 +378,6 @@ img {
|
||||
filter: var(--rust-logo-filter);
|
||||
}
|
||||
|
||||
.sidebar, .mobile-topbar, .sidebar-menu-toggle {
|
||||
background-color: var(--sidebar-background-color);
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
font-size: 0.875rem;
|
||||
flex: 0 0 200px;
|
||||
@ -400,7 +396,8 @@ img {
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.source .sidebar, #src-sidebar-toggle, #source-sidebar {
|
||||
.sidebar, .mobile-topbar, .sidebar-menu-toggle,
|
||||
#src-sidebar-toggle, #source-sidebar {
|
||||
background-color: var(--sidebar-background-color);
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,52 @@
|
||||
// The goal of this test is to ensure that the sidebar is working as expected in the source
|
||||
// code pages.
|
||||
goto: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html"
|
||||
// First: desktop mode.
|
||||
show-text: true
|
||||
|
||||
// First, check the sidebar colors.
|
||||
define-function: (
|
||||
"check-colors",
|
||||
(theme, color, background_color),
|
||||
[
|
||||
("local-storage", {
|
||||
"rustdoc-theme": |theme|,
|
||||
"rustdoc-use-system-theme": "false",
|
||||
}),
|
||||
("reload"),
|
||||
// Checking results colors.
|
||||
("assert-css", (".source .sidebar", {
|
||||
"color": |color|,
|
||||
"background-color": |background_color|
|
||||
}, ALL)),
|
||||
],
|
||||
)
|
||||
|
||||
call-function: (
|
||||
"check-colors",
|
||||
{
|
||||
"theme": "ayu",
|
||||
"color": "rgb(197, 197, 197)",
|
||||
"background_color": "rgb(20, 25, 31)",
|
||||
}
|
||||
)
|
||||
call-function: (
|
||||
"check-colors",
|
||||
{
|
||||
"theme": "dark",
|
||||
"color": "rgb(221, 221, 221)",
|
||||
"background_color": "rgb(80, 80, 80)",
|
||||
}
|
||||
)
|
||||
call-function: (
|
||||
"check-colors",
|
||||
{
|
||||
"theme": "light",
|
||||
"color": "rgb(0, 0, 0)",
|
||||
"background_color": "rgb(245, 245, 245)",
|
||||
}
|
||||
)
|
||||
|
||||
// Next, desktop mode layout.
|
||||
size: (1100, 800)
|
||||
// We check that the sidebar isn't expanded and has the expected width.
|
||||
assert-css: ("nav.sidebar", {"width": "50px"})
|
||||
|
@ -2,6 +2,50 @@
|
||||
goto: "file://" + |DOC_PATH| + "/test_docs/index.html"
|
||||
assert-property: (".sidebar", {"clientWidth": "200"})
|
||||
show-text: true
|
||||
|
||||
// First, check the sidebar colors.
|
||||
define-function: (
|
||||
"check-colors",
|
||||
(theme, color, background_color),
|
||||
[
|
||||
("local-storage", {
|
||||
"rustdoc-theme": |theme|,
|
||||
"rustdoc-use-system-theme": "false",
|
||||
}),
|
||||
("reload"),
|
||||
// Checking results colors.
|
||||
("assert-css", (".sidebar", {
|
||||
"color": |color|,
|
||||
"background-color": |background_color|
|
||||
}, ALL)),
|
||||
],
|
||||
)
|
||||
|
||||
call-function: (
|
||||
"check-colors",
|
||||
{
|
||||
"theme": "ayu",
|
||||
"color": "rgb(197, 197, 197)",
|
||||
"background_color": "rgb(20, 25, 31)",
|
||||
}
|
||||
)
|
||||
call-function: (
|
||||
"check-colors",
|
||||
{
|
||||
"theme": "dark",
|
||||
"color": "rgb(221, 221, 221)",
|
||||
"background_color": "rgb(80, 80, 80)",
|
||||
}
|
||||
)
|
||||
call-function: (
|
||||
"check-colors",
|
||||
{
|
||||
"theme": "light",
|
||||
"color": "rgb(0, 0, 0)",
|
||||
"background_color": "rgb(245, 245, 245)",
|
||||
}
|
||||
)
|
||||
|
||||
local-storage: {"rustdoc-theme": "light"}
|
||||
// We reload the page so the local storage settings are being used.
|
||||
reload:
|
||||
|
@ -1,13 +1,13 @@
|
||||
// compile-flags: -Z teach
|
||||
|
||||
trait SomeTrait {
|
||||
fn foo(); //~ associated function `foo` has no `self` parameter
|
||||
fn foo(&self);
|
||||
}
|
||||
struct S;
|
||||
impl SomeTrait for S {
|
||||
fn foo(&self) {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let trait_obj: &dyn SomeTrait = SomeTrait;
|
||||
//~^ ERROR expected value, found trait `SomeTrait`
|
||||
//~| ERROR E0038
|
||||
let trait_obj: &dyn SomeTrait = &S;
|
||||
|
||||
let &invalid = trait_obj;
|
||||
//~^ ERROR E0033
|
||||
|
@ -1,31 +1,3 @@
|
||||
error[E0423]: expected value, found trait `SomeTrait`
|
||||
--> $DIR/E0033-teach.rs:8:37
|
||||
|
|
||||
LL | let trait_obj: &dyn SomeTrait = SomeTrait;
|
||||
| ^^^^^^^^^ not a value
|
||||
|
||||
error[E0038]: the trait `SomeTrait` cannot be made into an object
|
||||
--> $DIR/E0033-teach.rs:8:20
|
||||
|
|
||||
LL | let trait_obj: &dyn SomeTrait = SomeTrait;
|
||||
| ^^^^^^^^^^^^^^ `SomeTrait` cannot be made into an object
|
||||
|
|
||||
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
|
||||
--> $DIR/E0033-teach.rs:4:8
|
||||
|
|
||||
LL | trait SomeTrait {
|
||||
| --------- this trait cannot be made into an object...
|
||||
LL | fn foo();
|
||||
| ^^^ ...because associated function `foo` has no `self` parameter
|
||||
help: consider turning `foo` into a method by giving it a `&self` argument
|
||||
|
|
||||
LL | fn foo(&self);
|
||||
| +++++
|
||||
help: alternatively, consider constraining `foo` so it does not apply to trait objects
|
||||
|
|
||||
LL | fn foo() where Self: Sized;
|
||||
| +++++++++++++++++
|
||||
|
||||
error[E0033]: type `&dyn SomeTrait` cannot be dereferenced
|
||||
--> $DIR/E0033-teach.rs:12:9
|
||||
|
|
||||
@ -36,7 +8,6 @@ LL | let &invalid = trait_obj;
|
||||
|
||||
You can read more about trait objects in the Trait Objects section of the Reference: https://doc.rust-lang.org/reference/types.html#trait-objects
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: aborting due to previous error
|
||||
|
||||
Some errors have detailed explanations: E0033, E0038, E0423.
|
||||
For more information about an error, try `rustc --explain E0033`.
|
||||
For more information about this error, try `rustc --explain E0033`.
|
||||
|
@ -1,11 +1,12 @@
|
||||
trait SomeTrait {
|
||||
fn foo(); //~ associated function `foo` has no `self` parameter
|
||||
fn foo(&self);
|
||||
}
|
||||
struct S;
|
||||
impl SomeTrait for S {
|
||||
fn foo(&self) {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let trait_obj: &dyn SomeTrait = SomeTrait;
|
||||
//~^ ERROR expected value, found trait `SomeTrait`
|
||||
//~| ERROR E0038
|
||||
let trait_obj: &dyn SomeTrait = &S;
|
||||
|
||||
let &invalid = trait_obj;
|
||||
//~^ ERROR E0033
|
||||
|
@ -1,38 +1,9 @@
|
||||
error[E0423]: expected value, found trait `SomeTrait`
|
||||
--> $DIR/E0033.rs:6:37
|
||||
|
|
||||
LL | let trait_obj: &dyn SomeTrait = SomeTrait;
|
||||
| ^^^^^^^^^ not a value
|
||||
|
||||
error[E0038]: the trait `SomeTrait` cannot be made into an object
|
||||
--> $DIR/E0033.rs:6:20
|
||||
|
|
||||
LL | let trait_obj: &dyn SomeTrait = SomeTrait;
|
||||
| ^^^^^^^^^^^^^^ `SomeTrait` cannot be made into an object
|
||||
|
|
||||
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
|
||||
--> $DIR/E0033.rs:2:8
|
||||
|
|
||||
LL | trait SomeTrait {
|
||||
| --------- this trait cannot be made into an object...
|
||||
LL | fn foo();
|
||||
| ^^^ ...because associated function `foo` has no `self` parameter
|
||||
help: consider turning `foo` into a method by giving it a `&self` argument
|
||||
|
|
||||
LL | fn foo(&self);
|
||||
| +++++
|
||||
help: alternatively, consider constraining `foo` so it does not apply to trait objects
|
||||
|
|
||||
LL | fn foo() where Self: Sized;
|
||||
| +++++++++++++++++
|
||||
|
||||
error[E0033]: type `&dyn SomeTrait` cannot be dereferenced
|
||||
--> $DIR/E0033.rs:10:9
|
||||
--> $DIR/E0033.rs:11:9
|
||||
|
|
||||
LL | let &invalid = trait_obj;
|
||||
| ^^^^^^^^ type `&dyn SomeTrait` cannot be dereferenced
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: aborting due to previous error
|
||||
|
||||
Some errors have detailed explanations: E0033, E0038, E0423.
|
||||
For more information about an error, try `rustc --explain E0033`.
|
||||
For more information about this error, try `rustc --explain E0033`.
|
||||
|
@ -7,10 +7,8 @@ fn main() {
|
||||
//~^ ERROR: character literal may only contain one codepoint
|
||||
|
||||
if x == y {}
|
||||
//~^ ERROR: can't compare `&str` with `char`
|
||||
if y == z {} // no error here
|
||||
if x == z {}
|
||||
//~^ ERROR: can't compare `&str` with `char`
|
||||
|
||||
let a: usize = "";
|
||||
//~^ ERROR: mismatched types
|
||||
|
@ -31,49 +31,14 @@ help: if you meant to write a `str` literal, use double quotes
|
||||
LL | let z = "ef";
|
||||
| ~~~~
|
||||
|
||||
error[E0277]: can't compare `&str` with `char`
|
||||
--> $DIR/lex-bad-char-literals-6.rs:9:10
|
||||
|
|
||||
LL | if x == y {}
|
||||
| ^^ no implementation for `&str == char`
|
||||
|
|
||||
= help: the trait `PartialEq<char>` is not implemented for `&str`
|
||||
= help: the following other types implement trait `PartialEq<Rhs>`:
|
||||
<&'a str as PartialEq<OsString>>
|
||||
<&'a str as PartialEq<String>>
|
||||
<&'b str as PartialEq<Cow<'a, str>>>
|
||||
<str as PartialEq<Cow<'a, str>>>
|
||||
<str as PartialEq<OsStr>>
|
||||
<str as PartialEq<OsString>>
|
||||
<str as PartialEq<String>>
|
||||
<str as PartialEq>
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/lex-bad-char-literals-6.rs:15:20
|
||||
--> $DIR/lex-bad-char-literals-6.rs:13:20
|
||||
|
|
||||
LL | let a: usize = "";
|
||||
| ----- ^^ expected `usize`, found `&str`
|
||||
| |
|
||||
| expected due to this
|
||||
|
||||
error[E0277]: can't compare `&str` with `char`
|
||||
--> $DIR/lex-bad-char-literals-6.rs:12:10
|
||||
|
|
||||
LL | if x == z {}
|
||||
| ^^ no implementation for `&str == char`
|
||||
|
|
||||
= help: the trait `PartialEq<char>` is not implemented for `&str`
|
||||
= help: the following other types implement trait `PartialEq<Rhs>`:
|
||||
<&'a str as PartialEq<OsString>>
|
||||
<&'a str as PartialEq<String>>
|
||||
<&'b str as PartialEq<Cow<'a, str>>>
|
||||
<str as PartialEq<Cow<'a, str>>>
|
||||
<str as PartialEq<OsStr>>
|
||||
<str as PartialEq<OsString>>
|
||||
<str as PartialEq<String>>
|
||||
<str as PartialEq>
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0277, E0308.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
@ -4,21 +4,13 @@ fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
|
||||
//~^ ERROR expected identifier, found keyword `fn`
|
||||
//~| ERROR expected identifier, found keyword `fn`
|
||||
//~| ERROR expected identifier, found keyword `fn`
|
||||
//~| ERROR cannot find trait `r#fn` in this scope
|
||||
//~| ERROR cannot find trait `r#fn` in this scope
|
||||
//~| ERROR cannot find trait `r#fn` in this scope
|
||||
//~| HELP a trait with a similar name exists
|
||||
//~| HELP a trait with a similar name exists
|
||||
//~| HELP a trait with a similar name exists
|
||||
//~| HELP escape `fn` to use it as an identifier
|
||||
//~| HELP escape `fn` to use it as an identifier
|
||||
//~| HELP escape `fn` to use it as an identifier
|
||||
//~| HELP use `Fn` to refer to the trait
|
||||
//~| HELP use `Fn` to refer to the trait
|
||||
//~| HELP use `Fn` to refer to the trait
|
||||
where
|
||||
G: fn(),
|
||||
//~^ ERROR expected identifier, found keyword `fn`
|
||||
//~| ERROR cannot find trait `r#fn` in this scope
|
||||
//~| HELP a trait with a similar name exists
|
||||
//~| HELP escape `fn` to use it as an identifier
|
||||
//~| HELP use `Fn` to refer to the trait
|
||||
{}
|
||||
|
||||
fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
|
||||
|
@ -2,48 +2,48 @@ error: expected identifier, found keyword `fn`
|
||||
--> $DIR/kw-in-trait-bounds.rs:3:10
|
||||
|
|
||||
LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
|
||||
| ^^ expected identifier, found keyword
|
||||
| ^^
|
||||
|
|
||||
help: escape `fn` to use it as an identifier
|
||||
help: use `Fn` to refer to the trait
|
||||
|
|
||||
LL | fn _f<F: r#fn(), G>(_: impl fn(), _: &dyn fn())
|
||||
| ++
|
||||
LL | fn _f<F: Fn(), G>(_: impl fn(), _: &dyn fn())
|
||||
| ~~
|
||||
|
||||
error: expected identifier, found keyword `fn`
|
||||
--> $DIR/kw-in-trait-bounds.rs:3:27
|
||||
|
|
||||
LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
|
||||
| ^^ expected identifier, found keyword
|
||||
| ^^
|
||||
|
|
||||
help: escape `fn` to use it as an identifier
|
||||
help: use `Fn` to refer to the trait
|
||||
|
|
||||
LL | fn _f<F: fn(), G>(_: impl r#fn(), _: &dyn fn())
|
||||
| ++
|
||||
LL | fn _f<F: fn(), G>(_: impl Fn(), _: &dyn fn())
|
||||
| ~~
|
||||
|
||||
error: expected identifier, found keyword `fn`
|
||||
--> $DIR/kw-in-trait-bounds.rs:3:41
|
||||
|
|
||||
LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
|
||||
| ^^ expected identifier, found keyword
|
||||
| ^^
|
||||
|
|
||||
help: escape `fn` to use it as an identifier
|
||||
help: use `Fn` to refer to the trait
|
||||
|
|
||||
LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn r#fn())
|
||||
| ++
|
||||
LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn Fn())
|
||||
| ~~
|
||||
|
||||
error: expected identifier, found keyword `fn`
|
||||
--> $DIR/kw-in-trait-bounds.rs:17:4
|
||||
--> $DIR/kw-in-trait-bounds.rs:11:4
|
||||
|
|
||||
LL | G: fn(),
|
||||
| ^^ expected identifier, found keyword
|
||||
| ^^
|
||||
|
|
||||
help: escape `fn` to use it as an identifier
|
||||
help: use `Fn` to refer to the trait
|
||||
|
|
||||
LL | G: r#fn(),
|
||||
| ++
|
||||
LL | G: Fn(),
|
||||
| ~~
|
||||
|
||||
error: expected identifier, found keyword `struct`
|
||||
--> $DIR/kw-in-trait-bounds.rs:24:10
|
||||
--> $DIR/kw-in-trait-bounds.rs:16:10
|
||||
|
|
||||
LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
|
||||
| ^^^^^^ expected identifier, found keyword
|
||||
@ -54,7 +54,7 @@ LL | fn _g<A: r#struct, B>(_: impl struct, _: &dyn struct)
|
||||
| ++
|
||||
|
||||
error: expected identifier, found keyword `struct`
|
||||
--> $DIR/kw-in-trait-bounds.rs:24:29
|
||||
--> $DIR/kw-in-trait-bounds.rs:16:29
|
||||
|
|
||||
LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
|
||||
| ^^^^^^ expected identifier, found keyword
|
||||
@ -65,7 +65,7 @@ LL | fn _g<A: struct, B>(_: impl r#struct, _: &dyn struct)
|
||||
| ++
|
||||
|
||||
error: expected identifier, found keyword `struct`
|
||||
--> $DIR/kw-in-trait-bounds.rs:24:45
|
||||
--> $DIR/kw-in-trait-bounds.rs:16:45
|
||||
|
|
||||
LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
|
||||
| ^^^^^^ expected identifier, found keyword
|
||||
@ -76,7 +76,7 @@ LL | fn _g<A: struct, B>(_: impl struct, _: &dyn r#struct)
|
||||
| ++
|
||||
|
||||
error: expected identifier, found keyword `struct`
|
||||
--> $DIR/kw-in-trait-bounds.rs:38:8
|
||||
--> $DIR/kw-in-trait-bounds.rs:30:8
|
||||
|
|
||||
LL | B: struct,
|
||||
| ^^^^^^ expected identifier, found keyword
|
||||
@ -86,44 +86,8 @@ help: escape `struct` to use it as an identifier
|
||||
LL | B: r#struct,
|
||||
| ++
|
||||
|
||||
error[E0405]: cannot find trait `r#fn` in this scope
|
||||
--> $DIR/kw-in-trait-bounds.rs:3:10
|
||||
|
|
||||
LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
|
||||
| ^^ help: a trait with a similar name exists (notice the capitalization): `Fn`
|
||||
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
|
||||
|
|
||||
= note: similarly named trait `Fn` defined here
|
||||
|
||||
error[E0405]: cannot find trait `r#fn` in this scope
|
||||
--> $DIR/kw-in-trait-bounds.rs:17:4
|
||||
|
|
||||
LL | G: fn(),
|
||||
| ^^ help: a trait with a similar name exists (notice the capitalization): `Fn`
|
||||
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
|
||||
|
|
||||
= note: similarly named trait `Fn` defined here
|
||||
|
||||
error[E0405]: cannot find trait `r#fn` in this scope
|
||||
--> $DIR/kw-in-trait-bounds.rs:3:27
|
||||
|
|
||||
LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
|
||||
| ^^ help: a trait with a similar name exists (notice the capitalization): `Fn`
|
||||
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
|
||||
|
|
||||
= note: similarly named trait `Fn` defined here
|
||||
|
||||
error[E0405]: cannot find trait `r#fn` in this scope
|
||||
--> $DIR/kw-in-trait-bounds.rs:3:41
|
||||
|
|
||||
LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
|
||||
| ^^ help: a trait with a similar name exists (notice the capitalization): `Fn`
|
||||
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
|
||||
|
|
||||
= note: similarly named trait `Fn` defined here
|
||||
|
||||
error[E0405]: cannot find trait `r#struct` in this scope
|
||||
--> $DIR/kw-in-trait-bounds.rs:24:10
|
||||
--> $DIR/kw-in-trait-bounds.rs:16:10
|
||||
|
|
||||
LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
|
||||
| ^^^^^^ help: a trait with a similar name exists (notice the capitalization): `Struct`
|
||||
@ -132,7 +96,7 @@ LL | trait Struct {}
|
||||
| ------------ similarly named trait `Struct` defined here
|
||||
|
||||
error[E0405]: cannot find trait `r#struct` in this scope
|
||||
--> $DIR/kw-in-trait-bounds.rs:38:8
|
||||
--> $DIR/kw-in-trait-bounds.rs:30:8
|
||||
|
|
||||
LL | B: struct,
|
||||
| ^^^^^^ help: a trait with a similar name exists (notice the capitalization): `Struct`
|
||||
@ -141,7 +105,7 @@ LL | trait Struct {}
|
||||
| ------------ similarly named trait `Struct` defined here
|
||||
|
||||
error[E0405]: cannot find trait `r#struct` in this scope
|
||||
--> $DIR/kw-in-trait-bounds.rs:24:29
|
||||
--> $DIR/kw-in-trait-bounds.rs:16:29
|
||||
|
|
||||
LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
|
||||
| ^^^^^^ help: a trait with a similar name exists (notice the capitalization): `Struct`
|
||||
@ -150,7 +114,7 @@ LL | trait Struct {}
|
||||
| ------------ similarly named trait `Struct` defined here
|
||||
|
||||
error[E0405]: cannot find trait `r#struct` in this scope
|
||||
--> $DIR/kw-in-trait-bounds.rs:24:45
|
||||
--> $DIR/kw-in-trait-bounds.rs:16:45
|
||||
|
|
||||
LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
|
||||
| ^^^^^^ help: a trait with a similar name exists (notice the capitalization): `Struct`
|
||||
@ -158,6 +122,6 @@ LL | fn _g<A: struct, B>(_: impl struct, _: &dyn struct)
|
||||
LL | trait Struct {}
|
||||
| ------------ similarly named trait `Struct` defined here
|
||||
|
||||
error: aborting due to 16 previous errors
|
||||
error: aborting due to 12 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0405`.
|
||||
|
12
src/test/ui/parser/recover-fn-trait-from-fn-kw.rs
Normal file
12
src/test/ui/parser/recover-fn-trait-from-fn-kw.rs
Normal file
@ -0,0 +1,12 @@
|
||||
fn foo(_: impl fn() -> i32) {}
|
||||
//~^ ERROR expected identifier, found keyword `fn`
|
||||
|
||||
fn foo2<T: fn(i32)>(_: T) {}
|
||||
//~^ ERROR expected identifier, found keyword `fn`
|
||||
|
||||
fn main() {
|
||||
foo(|| ());
|
||||
//~^ mismatched types
|
||||
foo2(|_: ()| {});
|
||||
//~^ type mismatch in closure arguments
|
||||
}
|
48
src/test/ui/parser/recover-fn-trait-from-fn-kw.stderr
Normal file
48
src/test/ui/parser/recover-fn-trait-from-fn-kw.stderr
Normal file
@ -0,0 +1,48 @@
|
||||
error: expected identifier, found keyword `fn`
|
||||
--> $DIR/recover-fn-trait-from-fn-kw.rs:1:16
|
||||
|
|
||||
LL | fn foo(_: impl fn() -> i32) {}
|
||||
| ^^
|
||||
|
|
||||
help: use `Fn` to refer to the trait
|
||||
|
|
||||
LL | fn foo(_: impl Fn() -> i32) {}
|
||||
| ~~
|
||||
|
||||
error: expected identifier, found keyword `fn`
|
||||
--> $DIR/recover-fn-trait-from-fn-kw.rs:4:12
|
||||
|
|
||||
LL | fn foo2<T: fn(i32)>(_: T) {}
|
||||
| ^^
|
||||
|
|
||||
help: use `Fn` to refer to the trait
|
||||
|
|
||||
LL | fn foo2<T: Fn(i32)>(_: T) {}
|
||||
| ~~
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/recover-fn-trait-from-fn-kw.rs:8:12
|
||||
|
|
||||
LL | foo(|| ());
|
||||
| ^^ expected `i32`, found `()`
|
||||
|
||||
error[E0631]: type mismatch in closure arguments
|
||||
--> $DIR/recover-fn-trait-from-fn-kw.rs:10:5
|
||||
|
|
||||
LL | foo2(|_: ()| {});
|
||||
| ^^^^ ------- found signature defined here
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected closure signature `fn(i32) -> _`
|
||||
found closure signature `fn(()) -> _`
|
||||
note: required by a bound in `foo2`
|
||||
--> $DIR/recover-fn-trait-from-fn-kw.rs:4:12
|
||||
|
|
||||
LL | fn foo2<T: fn(i32)>(_: T) {}
|
||||
| ^^^^^^^ required by this bound in `foo2`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0308, E0631.
|
||||
For more information about an error, try `rustc --explain E0308`.
|
@ -1,9 +1,13 @@
|
||||
// The purpose of this test is not to validate the output of the compiler.
|
||||
// Instead, it ensures the suggestion is generated without performing an arithmetic overflow.
|
||||
|
||||
fn main() {
|
||||
let x = not_found; //~ ERROR cannot find value `not_found` in this scope
|
||||
simd_gt::<()>(x);
|
||||
//~^ ERROR this associated function takes 0 generic arguments but 1 generic argument was supplied
|
||||
//~| ERROR cannot find function `simd_gt` in this scope
|
||||
struct S;
|
||||
impl S {
|
||||
fn foo(&self) {}
|
||||
}
|
||||
fn main() {
|
||||
let x = S;
|
||||
foo::<()>(x);
|
||||
//~^ ERROR this associated function takes 0 generic arguments but 1 generic argument was supplied
|
||||
//~| ERROR cannot find function `foo` in this scope
|
||||
}
|
||||
|
@ -1,30 +1,30 @@
|
||||
error[E0425]: cannot find value `not_found` in this scope
|
||||
--> $DIR/issue-104287.rs:5:13
|
||||
|
|
||||
LL | let x = not_found;
|
||||
| ^^^^^^^^^ not found in this scope
|
||||
|
||||
error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
|
||||
--> $DIR/issue-104287.rs:6:5
|
||||
--> $DIR/issue-104287.rs:10:5
|
||||
|
|
||||
LL | simd_gt::<()>(x);
|
||||
| ^^^^^^^------ help: remove these generics
|
||||
LL | foo::<()>(x);
|
||||
| ^^^------ help: remove these generics
|
||||
| |
|
||||
| expected 0 generic arguments
|
||||
|
|
||||
note: associated function defined here, with 0 generic parameters
|
||||
--> $DIR/issue-104287.rs:6:8
|
||||
|
|
||||
LL | fn foo(&self) {}
|
||||
| ^^^
|
||||
|
||||
error[E0425]: cannot find function `simd_gt` in this scope
|
||||
--> $DIR/issue-104287.rs:6:5
|
||||
error[E0425]: cannot find function `foo` in this scope
|
||||
--> $DIR/issue-104287.rs:10:5
|
||||
|
|
||||
LL | simd_gt::<()>(x);
|
||||
| ^^^^^^^ not found in this scope
|
||||
LL | foo::<()>(x);
|
||||
| ^^^ not found in this scope
|
||||
|
|
||||
help: use the `.` operator to call the method `SimdPartialOrd::simd_gt` on `[type error]`
|
||||
help: use the `.` operator to call the method `foo` on `&S`
|
||||
|
|
||||
LL - simd_gt::<()>(x);
|
||||
LL + x.simd_gt();
|
||||
LL - foo::<()>(x);
|
||||
LL + x.foo();
|
||||
|
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0107, E0425.
|
||||
For more information about an error, try `rustc --explain E0107`.
|
||||
|
@ -19,7 +19,7 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
|
||||
LL | const C: _ = || 42;
|
||||
| ^ not allowed in type signatures
|
||||
|
|
||||
note: however, the inferred type `[closure@$DIR/unnamable-types.rs:17:14: 17:16]` cannot be named
|
||||
note: however, the inferred type `[closure@unnamable-types.rs:17:14]` cannot be named
|
||||
--> $DIR/unnamable-types.rs:17:14
|
||||
|
|
||||
LL | const C: _ = || 42;
|
||||
@ -31,7 +31,7 @@ error: missing type for `const` item
|
||||
LL | const D = S { t: { let i = 0; move || -> i32 { i } } };
|
||||
| ^
|
||||
|
|
||||
note: however, the inferred type `S<[closure@$DIR/unnamable-types.rs:23:31: 23:45]>` cannot be named
|
||||
note: however, the inferred type `S<[closure@unnamable-types.rs:23:31]>` cannot be named
|
||||
--> $DIR/unnamable-types.rs:23:11
|
||||
|
|
||||
LL | const D = S { t: { let i = 0; move || -> i32 { i } } };
|
||||
|
17
src/test/ui/typeck/quiet-type-err-let-binding.rs
Normal file
17
src/test/ui/typeck/quiet-type-err-let-binding.rs
Normal file
@ -0,0 +1,17 @@
|
||||
// fn foo() -> String {
|
||||
// String::new()
|
||||
// }
|
||||
|
||||
fn test(s: &str) {
|
||||
println!("{}", s);
|
||||
}
|
||||
|
||||
fn test2(s: String) {
|
||||
println!("{}", s);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = foo(); //~ERROR cannot find function `foo` in this scope
|
||||
test(&x);
|
||||
test2(x); // Does not complain about `x` being a `&str`.
|
||||
}
|
9
src/test/ui/typeck/quiet-type-err-let-binding.stderr
Normal file
9
src/test/ui/typeck/quiet-type-err-let-binding.stderr
Normal file
@ -0,0 +1,9 @@
|
||||
error[E0425]: cannot find function `foo` in this scope
|
||||
--> $DIR/quiet-type-err-let-binding.rs:14:13
|
||||
|
|
||||
LL | let x = foo();
|
||||
| ^^^ not found in this scope
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0425`.
|
@ -220,3 +220,11 @@ fn value() -> Option<&'static _> {
|
||||
|
||||
const _: Option<_> = map(value);
|
||||
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
|
||||
|
||||
fn evens_squared(n: usize) -> _ {
|
||||
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
|
||||
(1..n).filter(|x| x % 2 == 0).map(|x| x * x)
|
||||
}
|
||||
|
||||
const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
|
||||
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
|
||||
|
@ -428,6 +428,27 @@ LL | const _: Option<_> = map(value);
|
||||
| not allowed in type signatures
|
||||
| help: replace with the correct type: `Option<u8>`
|
||||
|
||||
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
|
||||
--> $DIR/typeck_type_placeholder_item.rs:224:31
|
||||
|
|
||||
LL | fn evens_squared(n: usize) -> _ {
|
||||
| ^
|
||||
| |
|
||||
| not allowed in type signatures
|
||||
| help: replace with an appropriate return type: `impl Iterator<Item = usize>`
|
||||
|
||||
error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
|
||||
--> $DIR/typeck_type_placeholder_item.rs:229:10
|
||||
|
|
||||
LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
|
||||
| ^ not allowed in type signatures
|
||||
|
|
||||
note: however, the inferred type `Map<Filter<Range<i32>, [closure@typeck_type_placeholder_item.rs:229:29]>, [closure@typeck_type_placeholder_item.rs:229:49]>` cannot be named
|
||||
--> $DIR/typeck_type_placeholder_item.rs:229:14
|
||||
|
|
||||
LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
|
||||
--> $DIR/typeck_type_placeholder_item.rs:140:31
|
||||
|
|
||||
@ -636,7 +657,7 @@ LL | const D: _ = 42;
|
||||
| not allowed in type signatures
|
||||
| help: replace with the correct type: `i32`
|
||||
|
||||
error: aborting due to 69 previous errors
|
||||
error: aborting due to 71 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0121, E0282, E0403.
|
||||
For more information about an error, try `rustc --explain E0121`.
|
||||
|
Loading…
x
Reference in New Issue
Block a user