Allow combining -Cprofile-generate and -Cpanic=unwind when targeting MSVC.
The LLVM limitation that previously prevented this has been fixed in LLVM 9 which is older than the oldest LLVM version we currently support.
Fixes https://github.com/rust-lang/rust/issues/61002.
r? ``@nagisa`` (or anyone else from ``@rust-lang/wg-llvm)``
"rustc_span",
"rustc_symbol_mangling",
"rustc_target",
+ "smallvec",
"tempfile",
"tracing",
]
"serde_json",
]
-[[package]]
-name = "term"
-version = "0.0.0"
-dependencies = [
- "core",
- "std",
-]
-
[[package]]
name = "term"
version = "0.6.1"
"panic_unwind",
"proc_macro",
"std",
- "term 0.0.0",
]
[[package]]
exclude = [
"build",
"compiler/rustc_codegen_cranelift",
+ "src/test/rustdoc-gui",
# HACK(eddyb) This hardcodes the fact that our CI uses `/checkout/obj`.
"obj",
# The `x` binary is a thin wrapper that calls `x.py`, which initializes
}
ExprKind::Paren(expr) => {
vis.visit_expr(expr);
-
- // Nodes that are equal modulo `Paren` sugar no-ops should have the same IDs.
- *id = expr.id;
- vis.visit_span(span);
- visit_thin_attrs(attrs, vis);
- return;
}
ExprKind::Yield(expr) => {
visit_opt(expr, |expr| vis.visit_expr(expr));
// opaque type Foo1: Trait
let ty = self.lower_ty(
ty,
- ImplTraitContext::OtherOpaqueTy {
+ ImplTraitContext::TypeAliasesOpaqueTy {
capturable_lifetimes: &mut FxHashSet::default(),
- origin: hir::OpaqueTyOrigin::TyAlias,
},
);
let generics = self.lower_generics(gen, ImplTraitContext::disallowed());
span: Span,
body: Option<&Expr>,
) -> (&'hir hir::Ty<'hir>, hir::BodyId) {
- let mut capturable_lifetimes;
- let itctx = if self.sess.features_untracked().impl_trait_in_bindings {
- capturable_lifetimes = FxHashSet::default();
- ImplTraitContext::OtherOpaqueTy {
- capturable_lifetimes: &mut capturable_lifetimes,
- origin: hir::OpaqueTyOrigin::Misc,
- }
- } else {
- ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
- };
- let ty = self.lower_ty(ty, itctx);
+ let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Binding));
(ty, self.lower_const_body(span, body))
}
Some(ty) => {
let ty = self.lower_ty(
ty,
- ImplTraitContext::OtherOpaqueTy {
+ ImplTraitContext::TypeAliasesOpaqueTy {
capturable_lifetimes: &mut FxHashSet::default(),
- origin: hir::OpaqueTyOrigin::TyAlias,
},
);
hir::ImplItemKind::TyAlias(ty)
/// Origin: Either OpaqueTyOrigin::FnReturn or OpaqueTyOrigin::AsyncFn,
origin: hir::OpaqueTyOrigin,
},
- /// Impl trait in type aliases, consts and statics.
- OtherOpaqueTy {
+ /// Impl trait in type aliases.
+ TypeAliasesOpaqueTy {
/// Set of lifetimes that this opaque type can capture, if it uses
/// them. This includes lifetimes bound since we entered this context.
/// For example:
// FIXME(impl_trait): but `required_region_bounds` will ICE later
// anyway.
capturable_lifetimes: &'b mut FxHashSet<hir::LifetimeName>,
- /// Origin: Either OpaqueTyOrigin::Misc or OpaqueTyOrigin::Binding,
- origin: hir::OpaqueTyOrigin,
},
/// `impl Trait` is not accepted in this position.
Disallowed(ImplTraitPosition),
ReturnPositionOpaqueTy { fn_def_id, origin } => {
ReturnPositionOpaqueTy { fn_def_id: *fn_def_id, origin: *origin }
}
- OtherOpaqueTy { capturable_lifetimes, origin } => {
- OtherOpaqueTy { capturable_lifetimes, origin: *origin }
+ TypeAliasesOpaqueTy { capturable_lifetimes } => {
+ TypeAliasesOpaqueTy { capturable_lifetimes }
}
Disallowed(pos) => Disallowed(*pos),
}
//
// fn foo() -> impl Iterator<Item = impl Debug>
ImplTraitContext::ReturnPositionOpaqueTy { .. }
- | ImplTraitContext::OtherOpaqueTy { .. } => (true, itctx),
+ | ImplTraitContext::TypeAliasesOpaqueTy { .. } => (true, itctx),
// We are in the argument position, but within a dyn type:
//
capturable_lifetimes = FxHashSet::default();
(
true,
- ImplTraitContext::OtherOpaqueTy {
+ ImplTraitContext::TypeAliasesOpaqueTy {
capturable_lifetimes: &mut capturable_lifetimes,
- origin: hir::OpaqueTyOrigin::Misc,
},
)
}
None,
|this| this.lower_param_bounds(bounds, itctx),
),
- ImplTraitContext::OtherOpaqueTy { ref capturable_lifetimes, origin } => {
+ ImplTraitContext::TypeAliasesOpaqueTy { ref capturable_lifetimes } => {
// Reset capturable lifetimes, any nested impl trait
// types will inherit lifetimes from this opaque type,
// so don't need to capture them again.
- let nested_itctx = ImplTraitContext::OtherOpaqueTy {
+ let nested_itctx = ImplTraitContext::TypeAliasesOpaqueTy {
capturable_lifetimes: &mut FxHashSet::default(),
- origin,
};
self.lower_opaque_impl_trait(
span,
None,
- origin,
+ hir::OpaqueTyOrigin::TyAlias,
def_node_id,
Some(capturable_lifetimes),
|this| this.lower_param_bounds(bounds, nested_itctx),
}),
))
}
- ImplTraitContext::Disallowed(pos) => {
- let allowed_in = if self.sess.features_untracked().impl_trait_in_bindings {
- "bindings or function and inherent method return types"
- } else {
- "function and inherent method return types"
- };
+ ImplTraitContext::Disallowed(_) => {
let mut err = struct_span_err!(
self.sess,
t.span,
E0562,
"`impl Trait` not allowed outside of {}",
- allowed_in,
+ "function and method return types",
);
- if pos == ImplTraitPosition::Binding && self.sess.is_nightly_build() {
- err.help(
- "add `#![feature(impl_trait_in_bindings)]` to the crate \
- attributes to enable",
- );
- }
err.emit();
hir::TyKind::Err
}
}
fn lower_local(&mut self, l: &Local) -> hir::Local<'hir> {
- let ty = l.ty.as_ref().map(|t| {
- let mut capturable_lifetimes;
- self.lower_ty(
- t,
- if self.sess.features_untracked().impl_trait_in_bindings {
- capturable_lifetimes = FxHashSet::default();
- ImplTraitContext::OtherOpaqueTy {
- capturable_lifetimes: &mut capturable_lifetimes,
- origin: hir::OpaqueTyOrigin::Binding,
- }
- } else {
- ImplTraitContext::Disallowed(ImplTraitPosition::Binding)
- },
- )
- });
+ let ty = l
+ .ty
+ .as_ref()
+ .map(|t| self.lower_ty(t, ImplTraitContext::Disallowed(ImplTraitPosition::Binding)));
let init = l.init.as_ref().map(|e| self.lower_expr(e));
let hir_id = self.lower_node_id(l.id);
self.lower_attrs(hir_id, &l.attrs);
)),
_ => None,
});
- if let ImplTraitContext::OtherOpaqueTy { ref mut capturable_lifetimes, .. } = itctx {
+ if let ImplTraitContext::TypeAliasesOpaqueTy { ref mut capturable_lifetimes, .. } =
+ itctx
+ {
capturable_lifetimes.extend(lt_def_names.clone());
}
let res = this.lower_trait_ref(&p.trait_ref, itctx.reborrow());
- if let ImplTraitContext::OtherOpaqueTy { ref mut capturable_lifetimes, .. } = itctx {
+ if let ImplTraitContext::TypeAliasesOpaqueTy { ref mut capturable_lifetimes, .. } =
+ itctx
+ {
for param in lt_def_names {
capturable_lifetimes.remove(¶m);
}
insertion_sp,
suggestion,
);
+ err.note("assuming a `'static` lifetime...");
err.emit();
}
AnonymousLifetimeMode::PassThrough | AnonymousLifetimeMode::ReportError => {
sess,
span,
E0774,
- "`derive` may only be applied to structs, enums and unions",
+ "`derive` may only be applied to `struct`s, `enum`s and `union`s",
)
+ .span_label(span, "not applicable here")
+ .span_label(item.span(), "not a `struct`, `enum` or `union`")
.emit();
}
bad_target
_ => "for example, write `#[derive(Debug)]` for `Debug`".to_string(),
};
struct_span_err!(sess, lit.span, E0777, "expected path to a trait, found literal",)
+ .span_label(lit.span, "not a trait")
.help(&help_msg)
.emit();
}
}
_ => cx.span_bug(
trait_span,
- &format!(
- "unexpected substructure in \
- shallow `derive({})`",
- name
- ),
+ &format!("unexpected substructure in shallow `derive({})`", name),
),
}
}
) -> ast::Path {
let mut idents = self.path.iter().map(|s| Ident::new(*s, span)).collect();
let lt = mk_lifetimes(cx, span, &self.lifetime);
- let tys: Vec<P<ast::Ty>> =
- self.params.iter().map(|t| t.to_ty(cx, span, self_ty, self_generics)).collect();
- let params = lt
- .into_iter()
- .map(GenericArg::Lifetime)
- .chain(tys.into_iter().map(GenericArg::Type))
- .collect();
+ let tys = self.params.iter().map(|t| t.to_ty(cx, span, self_ty, self_generics));
+ let params =
+ lt.into_iter().map(GenericArg::Lifetime).chain(tys.map(GenericArg::Type)).collect();
match self.kind {
PathKind::Global => cx.path_all(span, true, idents, params),
jobserver = "0.1.22"
tempfile = "3.2"
pathdiff = "0.2.0"
+smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
rustc_serialize = { path = "../rustc_serialize" }
rustc_ast = { path = "../rustc_ast" }
use rustc_middle::ich::NodeIdHashingMode;
use rustc_middle::ty::layout::IntegerExt;
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
-use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt};
+use rustc_middle::ty::{self, AdtDef, ExistentialProjection, Ty, TyCtxt};
use rustc_target::abi::{Integer, TagEncoding, Variants};
+use smallvec::SmallVec;
use std::fmt::Write;
t: Ty<'tcx>,
qualified: bool,
) -> String {
+ let _prof = tcx.prof.generic_activity("compute_debuginfo_type_name");
+
let mut result = String::with_capacity(64);
let mut visited = FxHashSet::default();
push_debuginfo_type_name(tcx, t, qualified, &mut result, &mut visited);
// Pushes the name of the type as it should be stored in debuginfo on the
// `output` String. See also compute_debuginfo_type_name().
-pub fn push_debuginfo_type_name<'tcx>(
+fn push_debuginfo_type_name<'tcx>(
tcx: TyCtxt<'tcx>,
t: Ty<'tcx>,
qualified: bool,
for component_type in component_types {
push_debuginfo_type_name(tcx, component_type.expect_ty(), true, output, visited);
- output.push(',');
-
- // Natvis does not always like having spaces between parts of the type name
- // and this causes issues when we need to write a typename in natvis, for example
- // as part of a cast like the `HashMap` visualizer does.
- if !cpp_like_names {
- output.push(' ');
- }
+ push_arg_separator(cpp_like_names, output);
}
if !component_types.is_empty() {
- output.pop();
-
- if !cpp_like_names {
- output.pop();
- }
+ pop_arg_separator(output);
}
if cpp_like_names {
- push_close_angle_bracket(tcx, output);
+ push_close_angle_bracket(cpp_like_names, output);
} else {
output.push(')');
}
push_debuginfo_type_name(tcx, inner_type, qualified, output, visited);
if cpp_like_names {
- push_close_angle_bracket(tcx, output);
+ push_close_angle_bracket(cpp_like_names, output);
}
}
ty::Ref(_, inner_type, mutbl) => {
push_debuginfo_type_name(tcx, inner_type, qualified, output, visited);
if cpp_like_names && !is_slice_or_str {
- push_close_angle_bracket(tcx, output);
+ push_close_angle_bracket(cpp_like_names, output);
}
}
ty::Array(inner_type, len) => {
push_debuginfo_type_name(tcx, inner_type, true, output, visited);
if cpp_like_names {
- push_close_angle_bracket(tcx, output);
+ push_close_angle_bracket(cpp_like_names, output);
} else {
output.push(']');
}
}
ty::Dynamic(ref trait_data, ..) => {
- if cpp_like_names {
+ let auto_traits: SmallVec<[DefId; 4]> = trait_data.auto_traits().collect();
+
+ let has_enclosing_parens = if cpp_like_names {
output.push_str("dyn$<");
+ false
} else {
- output.push_str("dyn ");
- }
+ if trait_data.len() > 1 && auto_traits.len() != 0 {
+ // We need enclosing parens because there is more than one trait
+ output.push_str("(dyn ");
+ true
+ } else {
+ output.push_str("dyn ");
+ false
+ }
+ };
if let Some(principal) = trait_data.principal() {
let principal =
tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), principal);
push_item_name(tcx, principal.def_id, qualified, output);
- push_generic_params_internal(tcx, principal.substs, output, visited);
- } else {
- // The auto traits come ordered by `DefPathHash`, which guarantees stability if the
- // environment is stable (e.g., incremental builds) but not otherwise (e.g.,
- // updated compiler version, different target).
- //
- // To avoid that causing instabilities in test output, sort the auto-traits
- // alphabetically.
- let mut auto_traits: Vec<_> = trait_data
- .iter()
- .filter_map(|predicate| {
- match tcx.normalize_erasing_late_bound_regions(
- ty::ParamEnv::reveal_all(),
- predicate,
- ) {
- ty::ExistentialPredicate::AutoTrait(def_id) => {
- let mut name = String::new();
- push_item_name(tcx, def_id, true, &mut name);
- Some(name)
- }
- _ => None,
- }
+ let principal_has_generic_params =
+ push_generic_params_internal(tcx, principal.substs, output, visited);
+
+ let projection_bounds: SmallVec<[_; 4]> = trait_data
+ .projection_bounds()
+ .map(|bound| {
+ let ExistentialProjection { item_def_id, ty, .. } = bound.skip_binder();
+ (item_def_id, ty)
})
.collect();
- auto_traits.sort();
- for name in auto_traits {
- output.push_str(&name);
+ if projection_bounds.len() != 0 {
+ if principal_has_generic_params {
+ // push_generic_params_internal() above added a `>` but we actually
+ // want to add more items to that list, so remove that again.
+ pop_close_angle_bracket(output);
+ }
- if cpp_like_names {
- output.push_str(", ");
- } else {
- output.push_str(" + ");
+ for (item_def_id, ty) in projection_bounds {
+ push_arg_separator(cpp_like_names, output);
+
+ if cpp_like_names {
+ output.push_str("assoc$<");
+ push_item_name(tcx, item_def_id, false, output);
+ push_arg_separator(cpp_like_names, output);
+ push_debuginfo_type_name(tcx, ty, true, output, visited);
+ push_close_angle_bracket(cpp_like_names, output);
+ } else {
+ push_item_name(tcx, item_def_id, false, output);
+ output.push('=');
+ push_debuginfo_type_name(tcx, ty, true, output, visited);
+ }
}
+
+ push_close_angle_bracket(cpp_like_names, output);
}
- // Remove the trailing joining characters. For cpp_like_names
- // this is `, ` otherwise ` + `.
- output.pop();
- output.pop();
- if !cpp_like_names {
- output.pop();
+ if auto_traits.len() != 0 {
+ push_auto_trait_separator(cpp_like_names, output);
}
}
+ if auto_traits.len() != 0 {
+ let mut auto_traits: SmallVec<[String; 4]> = auto_traits
+ .into_iter()
+ .map(|def_id| {
+ let mut name = String::with_capacity(20);
+ push_item_name(tcx, def_id, true, &mut name);
+ name
+ })
+ .collect();
+ auto_traits.sort_unstable();
+
+ for auto_trait in auto_traits {
+ output.push_str(&auto_trait);
+ push_auto_trait_separator(cpp_like_names, output);
+ }
+
+ pop_auto_trait_separator(output);
+ }
+
if cpp_like_names {
- push_close_angle_bracket(tcx, output);
+ push_close_angle_bracket(cpp_like_names, output);
+ } else if has_enclosing_parens {
+ output.push(')');
}
}
ty::FnDef(..) | ty::FnPtr(_) => {
if !sig.inputs().is_empty() {
for ¶meter_type in sig.inputs() {
push_debuginfo_type_name(tcx, parameter_type, true, output, visited);
- output.push_str(", ");
+ push_arg_separator(cpp_like_names, output);
}
- output.pop();
- output.pop();
+ pop_arg_separator(output);
}
if sig.c_variadic {
output.push_str(&format!(", {}", variant));
}
}
- push_close_angle_bracket(tcx, output);
+ push_close_angle_bracket(true, output);
+ }
+
+ const NON_CPP_AUTO_TRAIT_SEPARATOR: &str = " + ";
+
+ fn push_auto_trait_separator(cpp_like_names: bool, output: &mut String) {
+ if cpp_like_names {
+ push_arg_separator(cpp_like_names, output);
+ } else {
+ output.push_str(NON_CPP_AUTO_TRAIT_SEPARATOR);
+ }
+ }
+
+ fn pop_auto_trait_separator(output: &mut String) {
+ if output.ends_with(NON_CPP_AUTO_TRAIT_SEPARATOR) {
+ output.truncate(output.len() - NON_CPP_AUTO_TRAIT_SEPARATOR.len());
+ } else {
+ pop_arg_separator(output);
+ }
}
}
substs: SubstsRef<'tcx>,
output: &mut String,
visited: &mut FxHashSet<Ty<'tcx>>,
-) {
+) -> bool {
if substs.non_erasable_generics().next().is_none() {
- return;
+ return false;
}
debug_assert_eq!(substs, tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), substs));
+ let cpp_like_names = cpp_like_names(tcx);
+
output.push('<');
for type_parameter in substs.non_erasable_generics() {
other => bug!("Unexpected non-erasable generic: {:?}", other),
}
- output.push_str(", ");
+ push_arg_separator(cpp_like_names, output);
}
+ pop_arg_separator(output);
+ push_close_angle_bracket(cpp_like_names, output);
- output.pop();
- output.pop();
-
- push_close_angle_bracket(tcx, output);
+ true
}
fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: &'tcx ty::Const<'tcx>, output: &mut String) {
}
pub fn push_generic_params<'tcx>(tcx: TyCtxt<'tcx>, substs: SubstsRef<'tcx>, output: &mut String) {
+ let _prof = tcx.prof.generic_activity("compute_debuginfo_type_name");
let mut visited = FxHashSet::default();
push_generic_params_internal(tcx, substs, output, &mut visited);
}
-fn push_close_angle_bracket<'tcx>(tcx: TyCtxt<'tcx>, output: &mut String) {
+fn push_close_angle_bracket(cpp_like_names: bool, output: &mut String) {
// MSVC debugger always treats `>>` as a shift, even when parsing templates,
// so add a space to avoid confusion.
- if cpp_like_names(tcx) && output.ends_with('>') {
+ if cpp_like_names && output.ends_with('>') {
output.push(' ')
};
output.push('>');
}
+fn pop_close_angle_bracket(output: &mut String) {
+ assert!(output.ends_with('>'), "'output' does not end with '>': {}", output);
+ output.pop();
+ if output.ends_with(' ') {
+ output.pop();
+ }
+}
+
+fn push_arg_separator(cpp_like_names: bool, output: &mut String) {
+ // Natvis does not always like having spaces between parts of the type name
+ // and this causes issues when we need to write a typename in natvis, for example
+ // as part of a cast like the `HashMap` visualizer does.
+ if cpp_like_names {
+ output.push(',');
+ } else {
+ output.push_str(", ");
+ };
+}
+
+fn pop_arg_separator(output: &mut String) {
+ if output.ends_with(' ') {
+ output.pop();
+ }
+
+ assert!(output.ends_with(','));
+
+ output.pop();
+}
+
fn cpp_like_names(tcx: TyCtxt<'_>) -> bool {
tcx.sess.target.is_like_msvc
}
E0718: include_str!("./error_codes/E0718.md"),
E0719: include_str!("./error_codes/E0719.md"),
E0720: include_str!("./error_codes/E0720.md"),
+E0722: include_str!("./error_codes/E0722.md"),
E0724: include_str!("./error_codes/E0724.md"),
E0725: include_str!("./error_codes/E0725.md"),
E0727: include_str!("./error_codes/E0727.md"),
E0754: include_str!("./error_codes/E0754.md"),
E0755: include_str!("./error_codes/E0755.md"),
E0756: include_str!("./error_codes/E0756.md"),
+E0757: include_str!("./error_codes/E0757.md"),
E0758: include_str!("./error_codes/E0758.md"),
E0759: include_str!("./error_codes/E0759.md"),
E0760: include_str!("./error_codes/E0760.md"),
E0711, // a feature has been declared with conflicting stability attributes
E0717, // rustc_promotable without stability attribute
// E0721, // `await` keyword
- E0722, // Malformed `#[optimize]` attribute
// E0723, unstable feature in `const` context
E0726, // non-explicit (not `'_`) elided lifetime in unsupported position
// E0738, // Removed; errored on `#[track_caller] fn`s in `extern "Rust" { ... }`.
- E0757, // `#[ffi_const]` functions cannot be `#[ffi_pure]`
E0772, // `'static' obligation coming from `impl dyn Trait {}` or `impl Foo for dyn Bar {}`.
}
--- /dev/null
+The `optimize` attribute was malformed.
+
+Erroneous code example:
+
+```compile_fail,E0722
+#![feature(optimize_attribute)]
+
+#[optimize(something)] // error: invalid argument
+pub fn something() {}
+```
+
+The `#[optimize]` attribute should be used as follows:
+
+- `#[optimize(size)]` -- instructs the optimization pipeline to generate code
+ that's smaller rather than faster
+
+- `#[optimize(speed)]` -- instructs the optimization pipeline to generate code
+ that's faster rather than smaller
+
+For example:
+
+```
+#![feature(optimize_attribute)]
+
+#[optimize(size)]
+pub fn something() {}
+```
+
+See [RFC 2412] for more details.
+
+[RFC 2412]: https://rust-lang.github.io/rfcs/2412-optimize-attr.html
--- /dev/null
+A function was given both the `ffi_const` and `ffi_pure` attributes.
+
+Erroneous code example:
+
+```compile_fail,E0757
+#![feature(ffi_const, ffi_pure)]
+
+extern "C" {
+ #[ffi_const]
+ #[ffi_pure] // error: `#[ffi_const]` function cannot be `#[ffi_pure]`
+ pub fn square(num: i32) -> i32;
+}
+```
+
+As `ffi_const` provides stronger guarantees than `ffi_pure`, remove the
+`ffi_pure` attribute:
+
+```
+#![feature(ffi_const)]
+
+extern "C" {
+ #[ffi_const]
+ pub fn square(num: i32) -> i32;
+}
+```
+
+You can get more information about `const` and `pure` in the [GCC documentation
+on Common Function Attributes]. The unstable Rust Book has more information
+about [`ffi_const`] and [`ffi_pure`].
+
+[GCC documentation on Common Function Attributes]: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
+[`ffi_const`]: https://doc.rust-lang.org/nightly/unstable-book/language-features/ffi-const.html
+[`ffi_pure`]: https://doc.rust-lang.org/nightly/unstable-book/language-features/ffi-pure.html
continue;
}
- if matches!(trace.kind, ExpnKind::Inlined) {
- new_labels
- .push((trace.call_site, "in the inlined copy of this code".to_string()));
- } else if always_backtrace {
+ if always_backtrace && !matches!(trace.kind, ExpnKind::Inlined) {
new_labels.push((
trace.def_site,
format!(
// and it needs an "in this macro invocation" label to match that.
let redundant_span = trace.call_site.contains(sp);
- if !redundant_span && matches!(trace.kind, ExpnKind::Macro(MacroKind::Bang, _))
- || always_backtrace
- {
+ if !redundant_span || always_backtrace {
+ let msg: Cow<'static, _> = match trace.kind {
+ ExpnKind::Macro(MacroKind::Attr, _) => {
+ "this procedural macro expansion".into()
+ }
+ ExpnKind::Macro(MacroKind::Derive, _) => {
+ "this derive macro expansion".into()
+ }
+ ExpnKind::Macro(MacroKind::Bang, _) => "this macro invocation".into(),
+ ExpnKind::Inlined => "the inlined copy of this code".into(),
+ ExpnKind::Root => "in the crate root".into(),
+ ExpnKind::AstPass(kind) => kind.descr().into(),
+ ExpnKind::Desugaring(kind) => {
+ format!("this {} desugaring", kind.descr()).into()
+ }
+ };
new_labels.push((
trace.call_site,
format!(
- "in this macro invocation{}",
+ "in {}{}",
+ msg,
if macro_backtrace.len() > 1 && always_backtrace {
// only specify order when the macro
// backtrace is multiple levels deep
/// Allows non-builtin attributes in inner attribute position.
(active, custom_inner_attributes, "1.30.0", Some(54726), None),
- /// Allows `impl Trait` in bindings (`let`, `const`, `static`).
- (incomplete, impl_trait_in_bindings, "1.30.0", Some(63065), None),
-
/// Allows using `reason` in lint attributes and the `#[expect(lint)]` lint check.
(active, lint_reasons, "1.31.0", Some(54503), None),
(removed, const_raw_ptr_to_usize_cast, "1.55.0", Some(51910), None,
Some("at compile-time, pointers do not have an integer value, so these casts cannot be properly supported")),
+ /// Allows `impl Trait` in bindings (`let`, `const`, `static`).
+ (removed, impl_trait_in_bindings, "1.55.0", Some(63065), None,
+ Some("the implementation was not maintainable, the feature may get reintroduced once the current refactorings are done")),
+
// -------------------------------------------------------------------------
// feature-group-end: removed features
// -------------------------------------------------------------------------
}
/// From whence the opaque type came.
-#[derive(Copy, Clone, Encodable, Decodable, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
pub enum OpaqueTyOrigin {
/// `-> impl Trait`
FnReturn,
/// `async fn`
AsyncFn,
- /// `let _: impl Trait = ...`
- Binding,
/// type aliases: `type Foo = impl Trait;`
TyAlias,
- /// Impl trait consts, statics, bounds.
- Misc,
}
/// The various kinds of types recognized by the compiler.
Node::Crate(_) | Node::Visibility(_) => None,
}
}
+
+ /// Returns `Constness::Const` when this node is a const fn/impl.
+ pub fn constness(&self) -> Constness {
+ match self {
+ Node::Item(Item {
+ kind: ItemKind::Fn(FnSig { header: FnHeader { constness, .. }, .. }, ..),
+ ..
+ })
+ | Node::TraitItem(TraitItem {
+ kind: TraitItemKind::Fn(FnSig { header: FnHeader { constness, .. }, .. }, ..),
+ ..
+ })
+ | Node::ImplItem(ImplItem {
+ kind: ImplItemKind::Fn(FnSig { header: FnHeader { constness, .. }, .. }, ..),
+ ..
+ })
+ | Node::Item(Item { kind: ItemKind::Impl(Impl { constness, .. }), .. }) => *constness,
+
+ _ => Constness::NotConst,
+ }
+ }
}
// Some nodes are used a lot. Make sure they don't unintentionally get bigger.
)
}
- /// A hacky variant of `canonicalize_query` that does not
- /// canonicalize `'static`. Unfortunately, the existing leak
- /// check treats `'static` differently in some cases (see also
- /// #33684), so if we are performing an operation that may need to
- /// prove "leak-check" related things, we leave `'static`
- /// alone.
- ///
- /// `'static` is also special cased when winnowing candidates when
- /// selecting implementation candidates, so we also have to leave `'static`
- /// alone for queries that do selection.
- //
- // FIXME(#48536): once the above issues are resolved, we can remove this
- // and just use `canonicalize_query`.
- pub fn canonicalize_hr_query_hack<V>(
+ /// A variant of `canonicalize_query` that does not
+ /// canonicalize `'static`. This is useful when
+ /// the query implementation can perform more efficient
+ /// handling of `'static` regions (e.g. trait evaluation).
+ pub fn canonicalize_query_keep_static<V>(
&self,
value: V,
query_state: &mut OriginalQueryValues<'tcx>,
let get_lifetimes = |sig| {
use rustc_hir::def::Namespace;
let mut s = String::new();
- let (_, (sig, reg)) = ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::TypeNS)
+ let (_, sig, reg) = ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::TypeNS)
.name_all_regions(sig)
.unwrap();
let lts: Vec<String> = reg.into_iter().map(|(_, kind)| kind.to_string()).collect();
}
};
if let Some((expected, found)) = expected_found {
- let expected_label = match exp_found {
- Mismatch::Variable(ef) => ef.expected.prefix_string(self.tcx),
- Mismatch::Fixed(s) => s.into(),
- };
- let found_label = match exp_found {
- Mismatch::Variable(ef) => ef.found.prefix_string(self.tcx),
- Mismatch::Fixed(s) => s.into(),
- };
- let exp_found = match exp_found {
- Mismatch::Variable(exp_found) => Some(exp_found),
- Mismatch::Fixed(_) => None,
+ let (expected_label, found_label, exp_found) = match exp_found {
+ Mismatch::Variable(ef) => (
+ ef.expected.prefix_string(self.tcx),
+ ef.found.prefix_string(self.tcx),
+ Some(ef),
+ ),
+ Mismatch::Fixed(s) => (s.into(), s.into(), None),
};
match (&terr, expected == found) {
(TypeError::Sorts(values), extra) => {
let new_lt = generics
.as_ref()
.and_then(|(parent_g, g)| {
- let possible: Vec<_> = (b'a'..=b'z').map(|c| format!("'{}", c as char)).collect();
+ let mut possible = (b'a'..=b'z').map(|c| format!("'{}", c as char));
let mut lts_names = g
.params
.iter()
);
}
let lts = lts_names.iter().map(|s| -> &str { &*s }).collect::<Vec<_>>();
- possible.into_iter().find(|candidate| !lts.contains(&candidate.as_str()))
+ possible.find(|candidate| !lts.contains(&candidate.as_str()))
})
.unwrap_or("'lt".to_string());
let add_lt_sugg = generics
span
};
- let is_named_and_not_impl_trait = |ty: Ty<'_>| {
- &ty.to_string() != "_" &&
- // FIXME: Remove this check after `impl_trait_in_bindings` is stabilized. #63527
- (!ty.is_impl_trait() || self.tcx.features().impl_trait_in_bindings)
- };
+ let is_named_and_not_impl_trait =
+ |ty: Ty<'_>| &ty.to_string() != "_" && !ty.is_impl_trait();
let ty_msg = match (local_visitor.found_node_ty, local_visitor.found_exact_method_call) {
(_, Some(_)) => String::new(),
--- /dev/null
+//! Error Reporting for when the lifetime for a type doesn't match the `impl` selected for a predicate
+//! to hold.
+
+use crate::infer::error_reporting::nice_region_error::NiceRegionError;
+use crate::infer::error_reporting::note_and_explain_region;
+use crate::infer::lexical_region_resolve::RegionResolutionError;
+use crate::infer::{SubregionOrigin, TypeTrace};
+use crate::traits::ObligationCauseCode;
+use rustc_data_structures::stable_set::FxHashSet;
+use rustc_errors::{Applicability, ErrorReported};
+use rustc_hir as hir;
+use rustc_hir::intravisit::Visitor;
+use rustc_middle::ty::{self, TypeVisitor};
+use rustc_span::MultiSpan;
+
+impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
+ pub(super) fn try_report_mismatched_static_lifetime(&self) -> Option<ErrorReported> {
+ let error = self.error.as_ref()?;
+ debug!("try_report_mismatched_static_lifetime {:?}", error);
+
+ let (origin, sub, sup) = match error.clone() {
+ RegionResolutionError::ConcreteFailure(origin, sub, sup) => (origin, sub, sup),
+ _ => return None,
+ };
+ if *sub != ty::RegionKind::ReStatic {
+ return None;
+ }
+ let cause = match origin {
+ SubregionOrigin::Subtype(box TypeTrace { ref cause, .. }) => cause,
+ _ => return None,
+ };
+ let (parent, impl_def_id) = match &cause.code {
+ ObligationCauseCode::MatchImpl(parent, impl_def_id) => (parent, impl_def_id),
+ _ => return None,
+ };
+ let binding_span = match **parent {
+ ObligationCauseCode::BindingObligation(_def_id, binding_span) => binding_span,
+ _ => return None,
+ };
+ let mut err = self.tcx().sess.struct_span_err(cause.span, "incompatible lifetime on type");
+ // FIXME: we should point at the lifetime
+ let mut multi_span: MultiSpan = vec![binding_span].into();
+ multi_span
+ .push_span_label(binding_span, "introduces a `'static` lifetime requirement".into());
+ err.span_note(multi_span, "because this has an unmet lifetime requirement");
+ note_and_explain_region(self.tcx(), &mut err, "", sup, "...");
+ if let Some(impl_node) = self.tcx().hir().get_if_local(*impl_def_id) {
+ // If an impl is local, then maybe this isn't what they want. Try to
+ // be as helpful as possible with implicit lifetimes.
+
+ // First, let's get the hir self type of the impl
+ let impl_self_ty = match impl_node {
+ hir::Node::Item(hir::Item {
+ kind: hir::ItemKind::Impl(hir::Impl { self_ty, .. }),
+ ..
+ }) => self_ty,
+ _ => bug!("Node not an impl."),
+ };
+
+ // Next, let's figure out the set of trait objects with implict static bounds
+ let ty = self.tcx().type_of(*impl_def_id);
+ let mut v = super::static_impl_trait::TraitObjectVisitor(FxHashSet::default());
+ v.visit_ty(ty);
+ let mut traits = vec![];
+ for matching_def_id in v.0 {
+ let mut hir_v =
+ super::static_impl_trait::HirTraitObjectVisitor(&mut traits, matching_def_id);
+ hir_v.visit_ty(&impl_self_ty);
+ }
+
+ if traits.is_empty() {
+ // If there are no trait object traits to point at, either because
+ // there aren't trait objects or because none are implicit, then just
+ // write a single note on the impl itself.
+
+ let impl_span = self.tcx().def_span(*impl_def_id);
+ err.span_note(impl_span, "...does not necessarily outlive the static lifetime introduced by the compatible `impl`");
+ } else {
+ // Otherwise, point at all implicit static lifetimes
+
+ err.note("...does not necessarily outlive the static lifetime introduced by the compatible `impl`");
+ for span in &traits {
+ err.span_note(*span, "this has an implicit `'static` lifetime requirement");
+ // It would be nice to put this immediately under the above note, but they get
+ // pushed to the end.
+ err.span_suggestion_verbose(
+ span.shrink_to_hi(),
+ "consider relaxing the implicit `'static` requirement",
+ " + '_".to_string(),
+ Applicability::MaybeIncorrect,
+ );
+ }
+ }
+ } else {
+ // Otherwise just point out the impl.
+
+ let impl_span = self.tcx().def_span(*impl_def_id);
+ err.span_note(impl_span, "...does not necessarily outlive the static lifetime introduced by the compatible `impl`");
+ }
+ err.emit();
+ Some(ErrorReported)
+ }
+}
mod different_lifetimes;
pub mod find_anon_type;
+mod mismatched_static_lifetime;
mod named_anon_conflict;
mod placeholder_error;
mod static_impl_trait;
.or_else(|| self.try_report_impl_not_conforming_to_trait())
.or_else(|| self.try_report_anon_anon_conflict())
.or_else(|| self.try_report_static_impl_trait())
+ .or_else(|| self.try_report_mismatched_static_lifetime())
}
pub fn regions(&self) -> Option<(Span, ty::Region<'tcx>, ty::Region<'tcx>)> {
use crate::infer::lexical_region_resolve::RegionResolutionError;
use crate::infer::{SubregionOrigin, TypeTrace};
use crate::traits::{ObligationCauseCode, UnifyReceiverContext};
+use rustc_data_structures::stable_set::FxHashSet;
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorReported};
use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::{walk_ty, ErasedMap, NestedVisitorMap, Visitor};
}
}
if let SubregionOrigin::Subtype(box TypeTrace { cause, .. }) = &sub_origin {
- if let ObligationCauseCode::ItemObligation(item_def_id) = cause.code {
+ let code = match &cause.code {
+ ObligationCauseCode::MatchImpl(parent, ..) => &**parent,
+ _ => &cause.code,
+ };
+ if let ObligationCauseCode::ItemObligation(item_def_id) = *code {
// Same case of `impl Foo for dyn Bar { fn qux(&self) {} }` introducing a `'static`
// lifetime as above, but called using a fully-qualified path to the method:
// `Foo::qux(bar)`.
- let mut v = TraitObjectVisitor(vec![]);
+ let mut v = TraitObjectVisitor(FxHashSet::default());
v.visit_ty(param.param_ty);
if let Some((ident, self_ty)) =
- self.get_impl_ident_and_self_ty_from_trait(item_def_id, &v.0[..])
+ self.get_impl_ident_and_self_ty_from_trait(item_def_id, &v.0)
{
- if self.suggest_constrain_dyn_trait_in_impl(&mut err, &v.0[..], ident, self_ty)
- {
+ if self.suggest_constrain_dyn_trait_in_impl(&mut err, &v.0, ident, self_ty) {
override_error_code = Some(ident);
}
}
fn get_impl_ident_and_self_ty_from_trait(
&self,
def_id: DefId,
- trait_objects: &[DefId],
+ trait_objects: &FxHashSet<DefId>,
) -> Option<(Ident, &'tcx hir::Ty<'tcx>)> {
let tcx = self.tcx();
match tcx.hir().get_if_local(def_id) {
// multiple `impl`s for the same trait like
// `impl Foo for Box<dyn Bar>` and `impl Foo for dyn Bar`.
// In that case, only the first one will get suggestions.
- let mut hir_v = HirTraitObjectVisitor(vec![], *did);
+ let mut traits = vec![];
+ let mut hir_v = HirTraitObjectVisitor(&mut traits, *did);
hir_v.visit_ty(self_ty);
- !hir_v.0.is_empty()
+ !traits.is_empty()
}) =>
{
Some(self_ty)
_ => return false,
};
- let mut v = TraitObjectVisitor(vec![]);
+ let mut v = TraitObjectVisitor(FxHashSet::default());
v.visit_ty(ty);
// Get the `Ident` of the method being called and the corresponding `impl` (to point at
// `Bar` in `impl Foo for dyn Bar {}` and the definition of the method being called).
let (ident, self_ty) =
- match self.get_impl_ident_and_self_ty_from_trait(instance.def_id(), &v.0[..]) {
+ match self.get_impl_ident_and_self_ty_from_trait(instance.def_id(), &v.0) {
Some((ident, self_ty)) => (ident, self_ty),
None => return false,
};
// Find the trait object types in the argument, so we point at *only* the trait object.
- self.suggest_constrain_dyn_trait_in_impl(err, &v.0[..], ident, self_ty)
+ self.suggest_constrain_dyn_trait_in_impl(err, &v.0, ident, self_ty)
}
fn suggest_constrain_dyn_trait_in_impl(
&self,
err: &mut DiagnosticBuilder<'_>,
- found_dids: &[DefId],
+ found_dids: &FxHashSet<DefId>,
ident: Ident,
self_ty: &hir::Ty<'_>,
) -> bool {
let mut suggested = false;
for found_did in found_dids {
- let mut hir_v = HirTraitObjectVisitor(vec![], *found_did);
+ let mut traits = vec![];
+ let mut hir_v = HirTraitObjectVisitor(&mut traits, *found_did);
hir_v.visit_ty(&self_ty);
- for span in &hir_v.0 {
+ for span in &traits {
let mut multi_span: MultiSpan = vec![*span].into();
multi_span.push_span_label(
*span,
}
/// Collect all the trait objects in a type that could have received an implicit `'static` lifetime.
-struct TraitObjectVisitor(Vec<DefId>);
+pub(super) struct TraitObjectVisitor(pub(super) FxHashSet<DefId>);
impl TypeVisitor<'_> for TraitObjectVisitor {
fn visit_ty(&mut self, t: Ty<'_>) -> ControlFlow<Self::BreakTy> {
match t.kind() {
ty::Dynamic(preds, RegionKind::ReStatic) => {
if let Some(def_id) = preds.principal_def_id() {
- self.0.push(def_id);
+ self.0.insert(def_id);
}
ControlFlow::CONTINUE
}
}
/// Collect all `hir::Ty<'_>` `Span`s for trait objects with an implicit lifetime.
-struct HirTraitObjectVisitor(Vec<Span>, DefId);
+pub(super) struct HirTraitObjectVisitor<'a>(pub(super) &'a mut Vec<Span>, pub(super) DefId);
-impl<'tcx> Visitor<'tcx> for HirTraitObjectVisitor {
+impl<'a, 'tcx> Visitor<'tcx> for HirTraitObjectVisitor<'a> {
type Map = ErasedMap<'tcx>;
fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
const_freshen_count: u32,
ty_freshen_map: FxHashMap<ty::InferTy, Ty<'tcx>>,
const_freshen_map: FxHashMap<ty::InferConst<'tcx>, &'tcx ty::Const<'tcx>>,
+ keep_static: bool,
}
impl<'a, 'tcx> TypeFreshener<'a, 'tcx> {
- pub fn new(infcx: &'a InferCtxt<'a, 'tcx>) -> TypeFreshener<'a, 'tcx> {
+ pub fn new(infcx: &'a InferCtxt<'a, 'tcx>, keep_static: bool) -> TypeFreshener<'a, 'tcx> {
TypeFreshener {
infcx,
ty_freshen_count: 0,
const_freshen_count: 0,
ty_freshen_map: Default::default(),
const_freshen_map: Default::default(),
+ keep_static,
}
}
r
}
- ty::ReStatic
- | ty::ReEarlyBound(..)
+ ty::ReEarlyBound(..)
| ty::ReFree(_)
| ty::ReVar(_)
| ty::RePlaceholder(..)
// replace all free regions with 'erased
self.tcx().lifetimes.re_erased
}
+ ty::ReStatic => {
+ if self.keep_static {
+ r
+ } else {
+ self.tcx().lifetimes.re_erased
+ }
+ }
}
}
let sub = var_data.normalize(self.tcx(), verify.region);
let verify_kind_ty = verify.kind.to_ty(self.tcx());
+ let verify_kind_ty = var_data.normalize(self.tcx(), verify_kind_ty);
if self.bound_is_met(&verify.bound, var_data, verify_kind_ty, sub) {
continue;
}
}
pub fn freshener<'b>(&'b self) -> TypeFreshener<'b, 'tcx> {
- freshen::TypeFreshener::new(self)
+ freshen::TypeFreshener::new(self, false)
+ }
+
+ /// Like `freshener`, but does not replace `'static` regions.
+ pub fn freshener_keep_static<'b>(&'b self) -> TypeFreshener<'b, 'tcx> {
+ freshen::TypeFreshener::new(self, true)
}
pub fn type_is_unconstrained_numeric(&'a self, ty: Ty<'_>) -> UnconstrainedNumeric {
match level {
Level::Allow => "-A",
Level::Warn => "-W",
- Level::ForceWarn => "--force-warns",
+ Level::ForceWarn => "--force-warn",
Level::Deny => "-D",
Level::Forbid => "-F",
},
fn no_lint_suggestion(&self, lint_name: &str) -> CheckLintNameResult<'_> {
let name_lower = lint_name.to_lowercase();
- let symbols =
- self.get_lints().iter().map(|l| Symbol::intern(&l.name_lower())).collect::<Vec<_>>();
if lint_name.chars().any(char::is_uppercase) && self.find_lints(&name_lower).is_ok() {
// First check if the lint name is (partly) in upper case instead of lower case...
- CheckLintNameResult::NoLint(Some(Symbol::intern(&name_lower)))
- } else {
- // ...if not, search for lints with a similar name
- let suggestion = find_best_match_for_name(&symbols, Symbol::intern(&name_lower), None);
- CheckLintNameResult::NoLint(suggestion)
+ return CheckLintNameResult::NoLint(Some(Symbol::intern(&name_lower)));
}
+ // ...if not, search for lints with a similar name
+ let groups = self.lint_groups.keys().copied().map(Symbol::intern);
+ let lints = self.lints.iter().map(|l| Symbol::intern(&l.name_lower()));
+ let names: Vec<Symbol> = groups.chain(lints).collect();
+ let suggestion = find_best_match_for_name(&names, Symbol::intern(&name_lower), None);
+ CheckLintNameResult::NoLint(suggestion)
}
fn check_tool_name_for_backwards_compat(
use rustc_span::{source_map::MultiSpan, Span, DUMMY_SP};
use tracing::debug;
-use std::cmp;
-
fn lint_levels(tcx: TyCtxt<'_>, (): ()) -> LintLevelMap {
let store = unerased_lint_store(tcx);
let crate_attrs = tcx.hir().attrs(CRATE_HIR_ID);
for &(ref lint_name, level) in &sess.opts.lint_opts {
store.check_lint_name_cmdline(sess, &lint_name, level, self.crate_attrs);
let orig_level = level;
-
- // If the cap is less than this specified level, e.g., if we've got
- // `--cap-lints allow` but we've also got `-D foo` then we ignore
- // this specification as the lint cap will set it to allow anyway.
- let level = cmp::min(level, self.sets.lint_cap);
-
let lint_flag_val = Symbol::intern(lint_name);
let ids = match store.find_lints(&lint_name) {
Err(_) => continue, // errors handled in check_lint_name_cmdline above
};
for id in ids {
+ // ForceWarn and Forbid cannot be overriden
+ if let Some((Level::ForceWarn | Level::Forbid, _)) = specs.get(&id) {
+ continue;
+ }
+
self.check_gated_lint(id, DUMMY_SP);
let src = LintLevelSource::CommandLine(lint_flag_val, orig_level);
specs.insert(id, (level, src));
}
}
- for lint_name in &sess.opts.force_warns {
- store.check_lint_name_cmdline(sess, lint_name, Level::ForceWarn, self.crate_attrs);
- let lints = store
- .find_lints(lint_name)
- .unwrap_or_else(|_| bug!("A valid lint failed to produce a lint ids"));
- for id in lints {
- let src = LintLevelSource::CommandLine(Symbol::intern(lint_name), Level::ForceWarn);
- specs.insert(id, (Level::ForceWarn, src));
- }
- }
-
self.cur = self.sets.list.push(LintSet { specs, parent: COMMAND_LINE });
}
match self {
Level::Allow => "allow",
Level::Warn => "warn",
- Level::ForceWarn => "force-warns",
+ Level::ForceWarn => "force-warn",
Level::Deny => "deny",
Level::Forbid => "forbid",
}
Node::Item(Item { kind: ItemKind::Fn(sig, _, _), .. })
| Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(sig, _), .. })
| Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(sig, _), .. }) => Some(&sig.decl),
- Node::Expr(Expr { kind: ExprKind::Closure(_, fn_decl, ..), .. }) => Some(fn_decl),
+ Node::Expr(Expr { kind: ExprKind::Closure(_, fn_decl, ..), .. })
+ | Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_decl, ..), .. }) => {
+ Some(fn_decl)
+ }
_ => None,
}
}
Level::Deny => "-D",
Level::Forbid => "-F",
Level::Allow => "-A",
- Level::ForceWarn => "--force-warns",
+ Level::ForceWarn => "--force-warn",
};
let hyphen_case_lint_name = name.replace("_", "-");
if lint_flag_val.as_str() == name {
/// Dereferencing a dangling pointer after it got freed.
PointerUseAfterFree(AllocId),
/// Used a pointer outside the bounds it is valid for.
+ /// (If `ptr_size > 0`, determines the size of the memory range that was expected to be in-bounds.)
PointerOutOfBounds {
alloc_id: AllocId,
- offset: Size,
- size: Size,
+ alloc_size: Size,
+ ptr_offset: i64,
+ ptr_size: Size,
msg: CheckInAllocMsg,
- allocation_size: Size,
},
/// Using an integer as a pointer in the wrong way.
DanglingIntPointer(u64, CheckInAllocMsg),
PointerUseAfterFree(a) => {
write!(f, "pointer to {} was dereferenced after this allocation got freed", a)
}
- PointerOutOfBounds { alloc_id, offset, size: Size::ZERO, msg, allocation_size } => {
+ PointerOutOfBounds { alloc_id, alloc_size, ptr_offset, ptr_size: Size::ZERO, msg } => {
write!(
f,
- "{}{} has size {}, so pointer at offset {} is out-of-bounds",
+ "{}{alloc_id} has size {alloc_size}, so pointer at offset {ptr_offset} is out-of-bounds",
msg,
- alloc_id,
- allocation_size.bytes(),
- offset.bytes(),
+ alloc_id = alloc_id,
+ alloc_size = alloc_size.bytes(),
+ ptr_offset = ptr_offset,
)
}
- PointerOutOfBounds { alloc_id, offset, size, msg, allocation_size } => write!(
+ PointerOutOfBounds { alloc_id, alloc_size, ptr_offset, ptr_size, msg } => write!(
f,
- "{}{} has size {}, so pointer to {} bytes starting at offset {} is out-of-bounds",
+ "{}{alloc_id} has size {alloc_size}, so pointer to {ptr_size} byte{ptr_size_p} starting at offset {ptr_offset} is out-of-bounds",
msg,
- alloc_id,
- allocation_size.bytes(),
- size.bytes(),
- offset.bytes(),
+ alloc_id = alloc_id,
+ alloc_size = alloc_size.bytes(),
+ ptr_size = ptr_size.bytes(),
+ ptr_size_p = pluralize!(ptr_size.bytes()),
+ ptr_offset = ptr_offset,
),
DanglingIntPointer(0, CheckInAllocMsg::InboundsTest) => {
write!(f, "null pointer is not a valid pointer for this operation")
i64::try_from(max_isize_plus_1 - 1).unwrap()
}
+ #[inline]
+ fn machine_usize_to_isize(&self, val: u64) -> i64 {
+ let val = val as i64;
+ // Now clamp into the machine_isize range.
+ if val > self.machine_isize_max() {
+ // This can only happen the the ptr size is < 64, so we know max_usize_plus_1 fits into
+ // i64.
+ let max_usize_plus_1 = 1u128 << self.pointer_size().bits();
+ val - i64::try_from(max_usize_plus_1).unwrap()
+ } else {
+ val
+ }
+ }
+
/// Helper function: truncate given value-"overflowed flag" pair to pointer size and
/// update "overflowed flag" if there was an overflow.
/// This should be called by all the other methods before returning!
/// span) for an *existing* error. Therefore, it is best-effort, and may never handle
/// all of the cases that the normal `ty::Ty`-based wfcheck does. This is fine,
/// because the `ty::Ty`-based wfcheck is always run.
- query diagnostic_hir_wf_check(key: (ty::Predicate<'tcx>, hir::HirId)) -> Option<traits::ObligationCause<'tcx>> {
+ query diagnostic_hir_wf_check(key: (ty::Predicate<'tcx>, traits::WellFormedLoc)) -> Option<traits::ObligationCause<'tcx>> {
eval_always
no_hash
desc { "performing HIR wf-checking for predicate {:?} at item {:?}", key.0, key.1 }
use rustc_data_structures::sync::Lrc;
use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_hir as hir;
-use rustc_hir::def_id::DefId;
+use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::Constness;
use rustc_span::symbol::Symbol;
use rustc_span::{Span, DUMMY_SP};
/// If `X` is the concrete type of an opaque type `impl Y`, then `X` must implement `Y`
OpaqueType,
- /// Well-formed checking. If a `HirId` is provided,
- /// it is used to perform HIR-based wf checking if an error
- /// occurs, in order to generate a more precise error message.
+ /// Well-formed checking. If a `WellFormedLoc` is provided,
+ /// then it will be used to eprform HIR-based wf checking
+ /// after an error occurs, in order to generate a more precise error span.
/// This is purely for diagnostic purposes - it is always
- /// correct to use `MiscObligation` instead
- WellFormed(Option<hir::HirId>),
+ /// correct to use `MiscObligation` instead, or to specify
+ /// `WellFormed(None)`
+ WellFormed(Option<WellFormedLoc>),
+
+ /// From `match_impl`. The cause for us having to match an impl, and the DefId we are matching against.
+ MatchImpl(Lrc<ObligationCauseCode<'tcx>>, DefId),
+}
+
+/// The 'location' at which we try to perform HIR-based wf checking.
+/// This information is used to obtain an `hir::Ty`, which
+/// we can walk in order to obtain precise spans for any
+/// 'nested' types (e.g. `Foo` in `Option<Foo>`).
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
+pub enum WellFormedLoc {
+ /// Use the type of the provided definition.
+ Ty(LocalDefId),
+ /// Use the type of the parameter of the provided function.
+ /// We cannot use `hir::Param`, since the function may
+ /// not have a body (e.g. a trait method definition)
+ Param {
+ /// The function to lookup the parameter in
+ function: LocalDefId,
+ /// The index of the parameter to use.
+ /// Parameters are indexed from 0, with the return type
+ /// being the last 'parameter'
+ param_idx: u16,
+ },
}
impl ObligationCauseCode<'_> {
// This is the impl for `&'a InternalSubsts<'a>`.
nop_list_lift! {substs; GenericArg<'a> => GenericArg<'tcx>}
-CloneLiftImpls! { for<'tcx> { Constness, } }
+CloneLiftImpls! { for<'tcx> { Constness, traits::WellFormedLoc, } }
pub mod tls {
use super::{ptr_eq, GlobalCtxt, TyCtxt};
}
}
+/// Folds through bound vars and placeholders, naming them
+struct RegionFolder<'a, 'tcx> {
+ tcx: TyCtxt<'tcx>,
+ current_index: ty::DebruijnIndex,
+ region_map: BTreeMap<ty::BoundRegion, ty::Region<'tcx>>,
+ name: &'a mut (dyn FnMut(ty::BoundRegion) -> ty::Region<'tcx> + 'a),
+}
+
+impl<'a, 'tcx> ty::TypeFolder<'tcx> for RegionFolder<'a, 'tcx> {
+ fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
+ self.tcx
+ }
+
+ fn fold_binder<T: TypeFoldable<'tcx>>(
+ &mut self,
+ t: ty::Binder<'tcx, T>,
+ ) -> ty::Binder<'tcx, T> {
+ self.current_index.shift_in(1);
+ let t = t.super_fold_with(self);
+ self.current_index.shift_out(1);
+ t
+ }
+
+ fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
+ match *t.kind() {
+ _ if t.has_vars_bound_at_or_above(self.current_index) || t.has_placeholders() => {
+ return t.super_fold_with(self);
+ }
+ _ => {}
+ }
+ t
+ }
+
+ fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
+ let name = &mut self.name;
+ let region = match *r {
+ ty::ReLateBound(_, br) => self.region_map.entry(br).or_insert_with(|| name(br)),
+ ty::RePlaceholder(ty::PlaceholderRegion { name: kind, .. }) => {
+ // If this is an anonymous placeholder, don't rename. Otherwise, in some
+ // async fns, we get a `for<'r> Send` bound
+ match kind {
+ ty::BrAnon(_) | ty::BrEnv => r,
+ _ => {
+ // Index doesn't matter, since this is just for naming and these never get bound
+ let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind };
+ self.region_map.entry(br).or_insert_with(|| name(br))
+ }
+ }
+ }
+ _ => return r,
+ };
+ if let ty::ReLateBound(debruijn1, br) = *region {
+ assert_eq!(debruijn1, ty::INNERMOST);
+ self.tcx.mk_region(ty::ReLateBound(self.current_index, br))
+ } else {
+ region
+ }
+ }
+}
+
// HACK(eddyb) limited to `FmtPrinter` because of `binder_depth`,
// `region_index` and `used_region_names`.
impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
pub fn name_all_regions<T>(
mut self,
value: &ty::Binder<'tcx, T>,
- ) -> Result<(Self, (T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>)), fmt::Error>
+ ) -> Result<(Self, T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>), fmt::Error>
where
T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>,
{
let mut empty = true;
let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| {
- write!(
- cx,
- "{}",
- if empty {
- empty = false;
- start
- } else {
- cont
- }
- )
+ let w = if empty {
+ empty = false;
+ start
+ } else {
+ cont
+ };
+ let _ = write!(cx, "{}", w);
+ };
+ let do_continue = |cx: &mut Self, cont: Symbol| {
+ let _ = write!(cx, "{}", cont);
};
define_scoped_cx!(self);
// aren't named. Eventually, we might just want this as the default, but
// this is not *quite* right and changes the ordering of some output
// anyways.
- let new_value = if self.tcx().sess.verbose() {
+ let (new_value, map) = if self.tcx().sess.verbose() {
// anon index + 1 (BrEnv takes 0) -> name
let mut region_map: BTreeMap<u32, Symbol> = BTreeMap::default();
let bound_vars = value.bound_vars();
for var in bound_vars {
match var {
ty::BoundVariableKind::Region(ty::BrNamed(_, name)) => {
- let _ = start_or_continue(&mut self, "for<", ", ");
- let _ = write!(self, "{}", name);
+ start_or_continue(&mut self, "for<", ", ");
+ do_continue(&mut self, name);
}
ty::BoundVariableKind::Region(ty::BrAnon(i)) => {
- let _ = start_or_continue(&mut self, "for<", ", ");
+ start_or_continue(&mut self, "for<", ", ");
let name = loop {
let name = name_by_region_index(region_index);
region_index += 1;
break name;
}
};
- let _ = write!(self, "{}", name);
+ do_continue(&mut self, name);
region_map.insert(i + 1, name);
}
ty::BoundVariableKind::Region(ty::BrEnv) => {
- let _ = start_or_continue(&mut self, "for<", ", ");
+ start_or_continue(&mut self, "for<", ", ");
let name = loop {
let name = name_by_region_index(region_index);
region_index += 1;
break name;
}
};
- let _ = write!(self, "{}", name);
+ do_continue(&mut self, name);
region_map.insert(0, name);
}
_ => continue,
}
}
- start_or_continue(&mut self, "", "> ")?;
+ start_or_continue(&mut self, "", "> ");
self.tcx.replace_late_bound_regions(value.clone(), |br| {
let kind = match br.kind {
))
})
} else {
- let new_value = self.tcx.replace_late_bound_regions(value.clone(), |br| {
- let _ = start_or_continue(&mut self, "for<", ", ");
+ let tcx = self.tcx;
+ let mut name = |br: ty::BoundRegion| {
+ start_or_continue(&mut self, "for<", ", ");
let kind = match br.kind {
ty::BrNamed(_, name) => {
- let _ = write!(self, "{}", name);
+ do_continue(&mut self, name);
br.kind
}
ty::BrAnon(_) | ty::BrEnv => {
break name;
}
};
- let _ = write!(self, "{}", name);
+ do_continue(&mut self, name);
ty::BrNamed(DefId::local(CRATE_DEF_INDEX), name)
}
};
- self.tcx.mk_region(ty::ReLateBound(
- ty::INNERMOST,
- ty::BoundRegion { var: br.var, kind },
- ))
- });
- start_or_continue(&mut self, "", "> ")?;
- new_value
+ tcx.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion { var: br.var, kind }))
+ };
+ let mut folder = RegionFolder {
+ tcx,
+ current_index: ty::INNERMOST,
+ name: &mut name,
+ region_map: BTreeMap::new(),
+ };
+ let new_value = value.clone().skip_binder().fold_with(&mut folder);
+ let region_map = folder.region_map;
+ start_or_continue(&mut self, "", "> ");
+ (new_value, region_map)
};
self.binder_depth += 1;
self.region_index = region_index;
- Ok((self, new_value))
+ Ok((self, new_value, map))
}
pub fn pretty_in_binder<T>(self, value: &ty::Binder<'tcx, T>) -> Result<Self, fmt::Error>
T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>,
{
let old_region_index = self.region_index;
- let (new, new_value) = self.name_all_regions(value)?;
- let mut inner = new_value.0.print(new)?;
+ let (new, new_value, _) = self.name_all_regions(value)?;
+ let mut inner = new_value.print(new)?;
inner.region_index = old_region_index;
inner.binder_depth -= 1;
Ok(inner)
T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>,
{
let old_region_index = self.region_index;
- let (new, new_value) = self.name_all_regions(value)?;
- let mut inner = f(&new_value.0, new)?;
+ let (new, new_value, _) = self.name_all_regions(value)?;
+ let mut inner = f(&new_value, new)?;
inner.region_index = old_region_index;
inner.binder_depth -= 1;
Ok(inner)
debug!("LateBoundRegionNameCollector::visit_region(r: {:?}, address: {:p})", r, &r);
if let ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrNamed(_, name), .. }) = *r {
self.used_region_names.insert(name);
+ } else if let ty::RePlaceholder(ty::PlaceholderRegion {
+ name: ty::BrNamed(_, name),
+ ..
+ }) = *r
+ {
+ self.used_region_names.insert(name);
}
r.super_visit_with(self)
}
use rustc_middle::ty::subst::Subst;
use rustc_middle::ty::{self, RegionVid, Ty};
use rustc_span::symbol::{kw, sym};
-use rustc_span::Span;
+use rustc_span::{BytePos, Span};
use crate::util::borrowck_errors;
} else {
"'_".to_string()
};
- let suggestion = if snippet.ends_with(';') {
+ let span = if snippet.ends_with(';') {
// `type X = impl Trait;`
- format!("{} + {};", &snippet[..snippet.len() - 1], suggestable_fr_name)
+ span.with_hi(span.hi() - BytePos(1))
} else {
- format!("{} + {}", snippet, suggestable_fr_name)
+ span
};
+ let suggestion = format!(" + {}", suggestable_fr_name);
+ let span = span.shrink_to_hi();
diag.span_suggestion(
span,
&format!(
use rustc_data_structures::fx::FxHashMap;
-use rustc_hir::def_id::DefId;
use rustc_index::vec::IndexVec;
use rustc_middle::infer::MemberConstraint;
use rustc_middle::ty::{self, Ty};
crate struct NllMemberConstraint<'tcx> {
next_constraint: Option<NllMemberConstraintIndex>,
- /// The opaque type whose hidden type is being inferred. (Used in error reporting.)
- crate opaque_type_def_id: DefId,
-
/// The span where the hidden type was instantiated.
crate definition_span: Span,
let constraint_index = self.constraints.push(NllMemberConstraint {
next_constraint,
member_region_vid,
- opaque_type_def_id: m_c.opaque_type_def_id,
definition_span: m_c.definition_span,
hidden_ty: m_c.hidden_ty,
start_index,
polonius_output: Option<Rc<PoloniusOutput>>,
) -> (Option<ClosureRegionRequirements<'tcx>>, RegionErrors<'tcx>) {
let mir_def_id = body.source.def_id();
- self.propagate_constraints(body, infcx.tcx);
+ self.propagate_constraints(body);
let mut errors_buffer = RegionErrors::new();
/// for each region variable until all the constraints are
/// satisfied. Note that some values may grow **too** large to be
/// feasible, but we check this later.
- fn propagate_constraints(&mut self, _body: &Body<'tcx>, tcx: TyCtxt<'tcx>) {
+ fn propagate_constraints(&mut self, _body: &Body<'tcx>) {
debug!("propagate_constraints()");
debug!("propagate_constraints: constraints={:#?}", {
// own.
let constraint_sccs = self.constraint_sccs.clone();
for scc in constraint_sccs.all_sccs() {
- self.compute_value_for_scc(scc, tcx);
+ self.compute_value_for_scc(scc);
}
// Sort the applied member constraints so we can binary search
/// computed, by unioning the values of its successors.
/// Assumes that all successors have been computed already
/// (which is assured by iterating over SCCs in dependency order).
- fn compute_value_for_scc(&mut self, scc_a: ConstraintSccIndex, tcx: TyCtxt<'tcx>) {
+ fn compute_value_for_scc(&mut self, scc_a: ConstraintSccIndex) {
let constraint_sccs = self.constraint_sccs.clone();
// Walk each SCC `B` such that `A: B`...
// Now take member constraints into account.
let member_constraints = self.member_constraints.clone();
for m_c_i in member_constraints.indices(scc_a) {
- self.apply_member_constraint(
- tcx,
- scc_a,
- m_c_i,
- member_constraints.choice_regions(m_c_i),
- );
+ self.apply_member_constraint(scc_a, m_c_i, member_constraints.choice_regions(m_c_i));
}
debug!(
/// If we make any changes, returns true, else false.
fn apply_member_constraint(
&mut self,
- tcx: TyCtxt<'tcx>,
scc: ConstraintSccIndex,
member_constraint_index: NllMemberConstraintIndex,
choice_regions: &[ty::RegionVid],
) -> bool {
debug!("apply_member_constraint(scc={:?}, choice_regions={:#?})", scc, choice_regions,);
- if let Some(uh_oh) =
- choice_regions.iter().find(|&&r| !self.universal_regions.is_universal_region(r))
- {
- // FIXME(#61773): This case can only occur with
- // `impl_trait_in_bindings`, I believe, and we are just
- // opting not to handle it for now. See #61773 for
- // details.
- tcx.sess.delay_span_bug(
- self.member_constraints[member_constraint_index].definition_span,
- &format!(
- "member constraint for `{:?}` has an option region `{:?}` \
- that is not a universal region",
- self.member_constraints[member_constraint_index].opaque_type_def_id, uh_oh,
- ),
- );
- return false;
- }
-
// Create a mutable vector of the options. We'll try to winnow
// them down.
let mut choice_regions: Vec<ty::RegionVid> = choice_regions.to_vec();
if let Err(terr) = self.eq_opaque_type_and_type(
mir_output_ty,
normalized_output_ty,
- mir_def_id,
Locations::All(output_span),
ConstraintCategory::BoringNoLocation,
) {
if let Err(err) = self.eq_opaque_type_and_type(
mir_output_ty,
user_provided_output_ty,
- mir_def_id,
Locations::All(output_span),
ConstraintCategory::BoringNoLocation,
) {
)
}
+ /// Try to relate `sub <: sup`
fn sub_types(
&mut self,
sub: Ty<'tcx>,
self.relate_types(sub, ty::Variance::Covariant, sup, locations, category)
}
- /// Try to relate `sub <: sup`; if this fails, instantiate opaque
- /// variables in `sub` with their inferred definitions and try
- /// again. This is used for opaque types in places (e.g., `let x:
- /// impl Foo = ..`).
- fn sub_types_or_anon(
- &mut self,
- sub: Ty<'tcx>,
- sup: Ty<'tcx>,
- locations: Locations,
- category: ConstraintCategory,
- ) -> Fallible<()> {
- if let Err(terr) = self.sub_types(sub, sup, locations, category) {
- if let ty::Opaque(..) = sup.kind() {
- // When you have `let x: impl Foo = ...` in a closure,
- // the resulting inferend values are stored with the
- // def-id of the base function.
- let parent_def_id =
- self.tcx().closure_base_def_id(self.body.source.def_id()).expect_local();
- return self.eq_opaque_type_and_type(sub, sup, parent_def_id, locations, category);
- } else {
- return Err(terr);
- }
- }
- Ok(())
- }
-
fn eq_types(
&mut self,
a: Ty<'tcx>,
}
/// Equates a type `anon_ty` that may contain opaque types whose
- /// values are to be inferred by the MIR with def-id `anon_owner_def_id`.
+ /// values are to be inferred by the MIR.
///
/// The type `revealed_ty` contains the same type as `anon_ty`, but with the
/// hidden types for impl traits revealed.
/// generics of `foo`). Note that `anon_ty` is not just the opaque type,
/// but the entire return type (which may contain opaque types within it).
/// * `revealed_ty` would be `Box<(T, u32)>`
- /// * `anon_owner_def_id` would be the def-id of `foo`
fn eq_opaque_type_and_type(
&mut self,
revealed_ty: Ty<'tcx>,
anon_ty: Ty<'tcx>,
- anon_owner_def_id: LocalDefId,
locations: Locations,
category: ConstraintCategory,
) -> Fallible<()> {
let tcx = infcx.tcx;
let param_env = self.param_env;
let body = self.body;
+ let mir_def_id = body.source.def_id().expect_local();
// the "concrete opaque types" maps
- let concrete_opaque_types = &tcx.typeck(anon_owner_def_id).concrete_opaque_types;
+ let concrete_opaque_types = &tcx.typeck(mir_def_id).concrete_opaque_types;
let mut opaque_type_values = VecMap::new();
- debug!("eq_opaque_type_and_type: mir_def_id={:?}", body.source.def_id());
+ debug!("eq_opaque_type_and_type: mir_def_id={:?}", mir_def_id);
let opaque_type_map = self.fully_perform_op(
locations,
category,
// any generic parameters.)
let (output_ty, opaque_type_map) =
obligations.add(infcx.instantiate_opaque_types(
- anon_owner_def_id,
+ mir_def_id,
dummy_body_id,
param_env,
anon_ty,
let rv_ty = rv.ty(body, tcx);
let rv_ty = self.normalize(rv_ty, location);
if let Err(terr) =
- self.sub_types_or_anon(rv_ty, place_ty, location.to_locations(), category)
+ self.sub_types(rv_ty, place_ty, location.to_locations(), category)
{
span_mirbug!(
self,
let locations = term_location.to_locations();
- if let Err(terr) =
- self.sub_types_or_anon(sig.output(), dest_ty, locations, category)
- {
+ if let Err(terr) = self.sub_types(sig.output(), dest_ty, locations, category) {
span_mirbug!(
self,
term,
)
}
- /// Check if the given pointerpoints to live memory of given `size` and `align`
+ /// Check if the given pointer points to live memory of given `size` and `align`
/// (ignoring `M::enforce_alignment`). The caller can control the error message for the
/// out-of-bounds case.
#[inline(always)]
None
}
Ok((alloc_id, offset, ptr)) => {
- let (allocation_size, alloc_align, ret_val) = alloc_size(alloc_id, offset, ptr)?;
+ let (alloc_size, alloc_align, ret_val) = alloc_size(alloc_id, offset, ptr)?;
// Test bounds. This also ensures non-null.
// It is sufficient to check this for the end pointer. Also check for overflow!
- if offset.checked_add(size, &self.tcx).map_or(true, |end| end > allocation_size) {
- throw_ub!(PointerOutOfBounds { alloc_id, offset, size, allocation_size, msg })
+ if offset.checked_add(size, &self.tcx).map_or(true, |end| end > alloc_size) {
+ throw_ub!(PointerOutOfBounds {
+ alloc_id,
+ alloc_size,
+ ptr_offset: self.machine_usize_to_isize(offset.bytes()),
+ ptr_size: size,
+ msg,
+ })
}
// Test align. Check this last; if both bounds and alignment are violated
// we want the error to be about the bounds.
permitted = true;
}
}
- let mut const_impls = true;
- tcx.for_each_relevant_impl(trait_id, substs.type_at(0), |imp| {
- if const_impls {
- if let hir::Constness::NotConst = tcx.impl_constness(imp) {
- const_impls = false;
+ if !permitted {
+ // if trait's impls are all const, permit the call.
+ let mut const_impls = true;
+ tcx.for_each_relevant_impl(trait_id, substs.type_at(0), |imp| {
+ if const_impls {
+ if let hir::Constness::NotConst = tcx.impl_constness(imp) {
+ const_impls = false;
+ }
}
+ });
+ if const_impls {
+ permitted = true;
}
- });
- if const_impls {
- permitted = true;
}
}
traits::NonStructuralMatchTy::Generator => {
"generators cannot be used in patterns".to_string()
}
- traits::NonStructuralMatchTy::Closure => {
- "closures cannot be used in patterns".to_string()
- }
traits::NonStructuralMatchTy::Param => {
bug!("use of a constant whose type is a parameter inside a pattern")
}
//! Defines the set of legal keys that can be used in queries.
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
-use rustc_hir::HirId;
use rustc_middle::infer::canonical::Canonical;
use rustc_middle::mir;
+use rustc_middle::traits;
use rustc_middle::ty::fast_reject::SimplifiedType;
use rustc_middle::ty::subst::{GenericArg, SubstsRef};
use rustc_middle::ty::{self, Ty, TyCtxt};
}
}
-impl<'tcx> Key for (ty::Predicate<'tcx>, HirId) {
+impl<'tcx> Key for (ty::Predicate<'tcx>, traits::WellFormedLoc) {
#[inline(always)]
fn query_crate_is_local(&self) -> bool {
true
optimize: OptLevel::No,
debuginfo: DebugInfo::None,
lint_opts: Vec::new(),
- force_warns: Vec::new(),
lint_cap: None,
describe_lints: false,
output_types: OutputTypes(BTreeMap::new()),
),
opt::multi_s(
"",
- "force-warns",
+ "force-warn",
"Specifiy lints that should warn even if \
they are allowed somewhere else",
"LINT",
matches: &getopts::Matches,
error_format: ErrorOutputType,
debugging_opts: &DebuggingOptions,
-) -> (Vec<(String, lint::Level)>, bool, Option<lint::Level>, Vec<String>) {
+) -> (Vec<(String, lint::Level)>, bool, Option<lint::Level>) {
let mut lint_opts_with_position = vec![];
let mut describe_lints = false;
- for level in [lint::Allow, lint::Warn, lint::Deny, lint::Forbid] {
- for (passed_arg_pos, lint_name) in matches.opt_strs_pos(level.as_str()) {
- let arg_pos = if let lint::Forbid = level {
- // HACK: forbid is always specified last, so it can't be overridden.
- // FIXME: remove this once <https://github.com/rust-lang/rust/issues/70819> is
- // fixed and `forbid` works as expected.
- usize::MAX
- } else {
- passed_arg_pos
- };
+ if !debugging_opts.unstable_options && matches.opt_present("force-warn") {
+ early_error(
+ error_format,
+ "the `-Z unstable-options` flag must also be passed to enable \
+ the flag `--force-warn=lints`",
+ );
+ }
+
+ for level in [lint::Allow, lint::Warn, lint::ForceWarn, lint::Deny, lint::Forbid] {
+ for (arg_pos, lint_name) in matches.opt_strs_pos(level.as_str()) {
if lint_name == "help" {
describe_lints = true;
} else {
.unwrap_or_else(|| early_error(error_format, &format!("unknown lint level: `{}`", cap)))
});
- if !debugging_opts.unstable_options && matches.opt_present("force-warns") {
- early_error(
- error_format,
- "the `-Z unstable-options` flag must also be passed to enable \
- the flag `--force-warns=lints`",
- );
- }
-
- let force_warns =
- matches.opt_strs("force-warns").into_iter().map(|name| name.replace('-', "_")).collect();
-
- (lint_opts, describe_lints, lint_cap, force_warns)
+ (lint_opts, describe_lints, lint_cap)
}
/// Parses the `--color` flag.
.unwrap_or_else(|e| early_error(error_format, &e[..]));
let mut debugging_opts = DebuggingOptions::build(matches, error_format);
- let (lint_opts, describe_lints, lint_cap, force_warns) =
+ let (lint_opts, describe_lints, lint_cap) =
get_cmd_lint_options(matches, error_format, &debugging_opts);
check_debug_option_stability(&debugging_opts, error_format, json_rendered);
optimize: opt_level,
debuginfo,
lint_opts,
- force_warns,
lint_cap,
describe_lints,
output_types,
debuginfo: DebugInfo [TRACKED],
lint_opts: Vec<(String, lint::Level)> [TRACKED_NO_CRATE_HASH],
lint_cap: Option<lint::Level> [TRACKED_NO_CRATE_HASH],
- force_warns: Vec<String> [TRACKED_NO_CRATE_HASH],
describe_lints: bool [UNTRACKED],
output_types: OutputTypes [TRACKED],
search_paths: Vec<SearchPath> [UNTRACKED],
}
impl AstPass {
- fn descr(self) -> &'static str {
+ pub fn descr(self) -> &'static str {
match self {
AstPass::StdImports => "standard library imports",
AstPass::TestHarness => "test harness",
impl DesugaringKind {
/// The description wording should combine well with "desugaring of {}".
- fn descr(self) -> &'static str {
+ pub fn descr(self) -> &'static str {
match self {
DesugaringKind::CondTemporary => "`if` or `while` condition",
DesugaringKind::Async => "`async` block or function",
}
// These opaque type inherit all lifetime parameters from their
// parent, so we have to check them all.
- hir::OpaqueTyOrigin::Binding
- | hir::OpaqueTyOrigin::TyAlias
- | hir::OpaqueTyOrigin::Misc => 0,
+ hir::OpaqueTyOrigin::TyAlias => 0,
};
let span = tcx.def_span(def_id);
may_define_opaque_type(tcx, self.parent_def_id, opaque_hir_id),
origin,
),
- _ => (def_scope_default(), hir::OpaqueTyOrigin::Misc),
+ _ => (def_scope_default(), hir::OpaqueTyOrigin::TyAlias),
};
if in_definition_scope {
let opaque_type_key =
SelectionError::Unimplemented => {
// If this obligation was generated as a result of well-formed checking, see if we
// can get a better error message by performing HIR-based well formed checking.
- if let ObligationCauseCode::WellFormed(Some(wf_hir_id)) =
+ if let ObligationCauseCode::WellFormed(Some(wf_loc)) =
root_obligation.cause.code.peel_derives()
{
if let Some(cause) =
- self.tcx.diagnostic_hir_wf_check((obligation.predicate, *wf_hir_id))
+ self.tcx.diagnostic_hir_wf_check((obligation.predicate, wf_loc.clone()))
{
obligation.cause = cause;
span = obligation.cause.span;
| ObligationCauseCode::UnifyReceiver(..)
| ObligationCauseCode::OpaqueType
| ObligationCauseCode::MiscObligation
- | ObligationCauseCode::WellFormed(..) => {}
+ | ObligationCauseCode::WellFormed(..)
+ | ObligationCauseCode::MatchImpl(..) => {}
ObligationCauseCode::SliceOrArrayElem => {
err.note("slice and array elements must have `Sized` type");
}
ObligationCauseCode::ItemObligation(item_def_id) => {
let item_name = tcx.def_path_str(item_def_id);
let msg = format!("required by `{}`", item_name);
- if let Some(sp) = tcx.hir().span_if_local(item_def_id) {
- let sp = tcx.sess.source_map().guess_head_span(sp);
- err.span_label(sp, &msg);
- } else {
- err.note(&msg);
- }
+ let sp = tcx
+ .hir()
+ .span_if_local(item_def_id)
+ .unwrap_or_else(|| tcx.def_span(item_def_id));
+ let sp = tcx.sess.source_map().guess_head_span(sp);
+ err.span_note(sp, &msg);
}
ObligationCauseCode::BindingObligation(item_def_id, span) => {
let item_name = tcx.def_path_str(item_def_id);
if span != DUMMY_SP {
err.span_label(span, &msg);
} else {
- err.note(&msg);
+ err.span_note(
+ tcx.def_span(item_def_id),
+ &format!("required by a bound in `{}`", item_name),
+ );
}
}
ObligationCauseCode::ObjectCastObligation(object_ty) => {
if self.tcx.sess.is_nightly_build() && is_const_fn {
err.help(
- "create an inline `const` block, see RFC \
- #2920 <https://github.com/rust-lang/rfcs/pull/2920> \
- for more information",
+ "create an inline `const` block, see RFC #2920 \
+ <https://github.com/rust-lang/rfcs/pull/2920> for more information",
);
}
}
self.tcx.for_each_relevant_impl(
parent_def_id,
parent_trait_ref.self_ty().skip_binder(),
- |impl_def_id| {
- candidates.push(impl_def_id);
+ |impl_def_id| match self.tcx.hir().get_if_local(impl_def_id) {
+ Some(Node::Item(hir::Item {
+ kind: hir::ItemKind::Impl(hir::Impl { .. }),
+ ..
+ })) => {
+ candidates.push(impl_def_id);
+ }
+ _ => {}
},
);
match &candidates[..] {
let project_obligation = obligation.with(binder.rebind(data));
self.process_projection_obligation(
+ obligation,
project_obligation,
&mut pending_obligation.stalled_on,
)
let project_obligation = obligation.with(Binder::dummy(*data));
self.process_projection_obligation(
+ obligation,
project_obligation,
&mut pending_obligation.stalled_on,
)
fn process_projection_obligation(
&mut self,
+ obligation: &PredicateObligation<'tcx>,
project_obligation: PolyProjectionObligation<'tcx>,
stalled_on: &mut Vec<TyOrConstInferVar<'tcx>>,
) -> ProcessResult<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>> {
let tcx = self.selcx.tcx();
+
+ if obligation.predicate.is_global() {
+ // no type variables present, can use evaluation for better caching.
+ // FIXME: consider caching errors too.
+ if self.selcx.infcx().predicate_must_hold_considering_regions(obligation) {
+ return ProcessResult::Changed(vec![]);
+ } else {
+ tracing::debug!("Does NOT hold: {:?}", obligation);
+ }
+ }
+
match project::poly_project_and_unify_type(self.selcx, &project_obligation) {
Ok(Ok(Some(os))) => ProcessResult::Changed(mk_pending(os)),
Ok(Ok(None)) => {
obligation: &PredicateObligation<'tcx>,
) -> Result<EvaluationResult, OverflowError> {
let mut _orig_values = OriginalQueryValues::default();
- let c_pred = self
- .canonicalize_query(obligation.param_env.and(obligation.predicate), &mut _orig_values);
+ let c_pred = self.canonicalize_query_keep_static(
+ obligation.param_env.and(obligation.predicate),
+ &mut _orig_values,
+ );
// Run canonical query. If overflow occurs, rerun from scratch but this time
// in standard trait query mode so that overflow is handled appropriately
// within `SelectionContext`.
// so we cannot canonicalize it.
let c_data = self
.infcx
- .canonicalize_hr_query_hack(self.param_env.and(data), &mut orig_values);
+ .canonicalize_query_keep_static(self.param_env.and(data), &mut orig_values);
debug!("QueryNormalizer: c_data = {:#?}", c_data);
debug!("QueryNormalizer: orig_values = {:#?}", orig_values);
match tcx.normalize_projection_ty(c_data) {
// so we cannot canonicalize it.
let c_data = self
.infcx
- .canonicalize_hr_query_hack(self.param_env.and(data), &mut orig_values);
+ .canonicalize_query_keep_static(self.param_env.and(data), &mut orig_values);
debug!("QueryNormalizer: c_data = {:#?}", c_data);
debug!("QueryNormalizer: orig_values = {:#?}", orig_values);
let normalized_ty = match tcx.normalize_projection_ty(c_data) {
}
// FIXME(#33684) -- We need to use
- // `canonicalize_hr_query_hack` here because of things
+ // `canonicalize_query_keep_static` here because of things
// like the subtype query, which go awry around
// `'static` otherwise.
let mut canonical_var_values = OriginalQueryValues::default();
let old_param_env = query_key.param_env;
- let canonical_self = infcx.canonicalize_hr_query_hack(query_key, &mut canonical_var_values);
+ let canonical_self =
+ infcx.canonicalize_query_keep_static(query_key, &mut canonical_var_values);
let canonical_result = Self::perform_query(infcx.tcx, canonical_self)?;
let InferOk { value, obligations } = infcx
pub fn new(infcx: &'cx InferCtxt<'cx, 'tcx>) -> SelectionContext<'cx, 'tcx> {
SelectionContext {
infcx,
- freshener: infcx.freshener(),
+ freshener: infcx.freshener_keep_static(),
intercrate: false,
intercrate_ambiguity_causes: None,
allow_negative_impls: false,
pub fn intercrate(infcx: &'cx InferCtxt<'cx, 'tcx>) -> SelectionContext<'cx, 'tcx> {
SelectionContext {
infcx,
- freshener: infcx.freshener(),
+ freshener: infcx.freshener_keep_static(),
intercrate: true,
intercrate_ambiguity_causes: None,
allow_negative_impls: false,
debug!(?allow_negative_impls, "with_negative");
SelectionContext {
infcx,
- freshener: infcx.freshener(),
+ freshener: infcx.freshener_keep_static(),
intercrate: false,
intercrate_ambiguity_causes: None,
allow_negative_impls,
debug!(?query_mode, "with_query_mode");
SelectionContext {
infcx,
- freshener: infcx.freshener(),
+ freshener: infcx.freshener_keep_static(),
intercrate: false,
intercrate_ambiguity_causes: None,
allow_negative_impls: false,
debug!(?impl_trait_ref, ?placeholder_obligation_trait_ref);
+ let cause = ObligationCause::new(
+ obligation.cause.span,
+ obligation.cause.body_id,
+ ObligationCauseCode::MatchImpl(Lrc::new(obligation.cause.code.clone()), impl_def_id),
+ );
+
let InferOk { obligations, .. } = self
.infcx
- .at(&obligation.cause, obligation.param_env)
+ .at(&cause, obligation.param_env)
.eq(placeholder_obligation_trait_ref, impl_trait_ref)
.map_err(|e| debug!("match_impl: failed eq_trait_refs due to `{}`", e))?;
nested_obligations.extend(obligations);
Opaque,
Generator,
Projection,
- Closure,
}
/// This method traverses the structure of `ty`, trying to find an
ty::Generator(..) | ty::GeneratorWitness(..) => {
return ControlFlow::Break(NonStructuralMatchTy::Generator);
}
- ty::Closure(..) => {
- return ControlFlow::Break(NonStructuralMatchTy::Closure);
- }
ty::RawPtr(..) => {
// structural-match ignores substructure of
// `*const _`/`*mut _`, so skip `super_visit_with`.
// First check all contained types and then tell the caller to continue searching.
return ty.super_visit_with(self);
}
- ty::Infer(_) | ty::Placeholder(_) | ty::Bound(..) => {
+ ty::Closure(..) | ty::Infer(_) | ty::Placeholder(_) | ty::Bound(..) => {
bug!("unexpected type during structural-match checking: {:?}", ty);
}
ty::Error(_) => {
this does nothing because the given bound is not \
a default; only `?Sized` is supported",
);
+ return false;
}
}
}
fcx.resume_yield_tys = Some((resume_ty, yield_ty));
}
- let outer_def_id = tcx.closure_base_def_id(hir.local_def_id(fn_id).to_def_id()).expect_local();
- let outer_hir_id = hir.local_def_id_to_hir_id(outer_def_id);
- GatherLocalsVisitor::new(&fcx, outer_hir_id).visit_body(body);
+ GatherLocalsVisitor::new(&fcx).visit_body(body);
// C-variadic fns also have a `VaList` input that's not listed in `fn_sig`
// (as it's created inside the body itself, not passed in from outside).
span: Span,
origin: &hir::OpaqueTyOrigin,
) -> Result<(), ErrorReported> {
- if let Err(partially_expanded_type) = tcx.try_expand_impl_trait_type(def_id.to_def_id(), substs)
- {
+ if tcx.try_expand_impl_trait_type(def_id.to_def_id(), substs).is_err() {
match origin {
hir::OpaqueTyOrigin::AsyncFn => async_opaque_type_cycle_error(tcx, span),
- hir::OpaqueTyOrigin::Binding => {
- binding_opaque_type_cycle_error(tcx, def_id, span, partially_expanded_type)
- }
_ => opaque_type_cycle_error(tcx, def_id, span),
}
Err(ErrorReported)
// Checked when type checking the function containing them.
hir::OpaqueTyOrigin::FnReturn | hir::OpaqueTyOrigin::AsyncFn => return,
// Can have different predicates to their defining use
- hir::OpaqueTyOrigin::Binding | hir::OpaqueTyOrigin::Misc | hir::OpaqueTyOrigin::TyAlias => {
- }
+ hir::OpaqueTyOrigin::TyAlias => {}
}
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
use rustc_trait_selection::traits::{
self, ObligationCause, ObligationCauseCode, StatementAsExpression, TraitEngine, TraitEngineExt,
+ WellFormedLoc,
};
use std::collections::hash_map::Entry;
&self,
span: Span,
value: T,
- hir_id: hir::HirId,
+ loc: WellFormedLoc,
) -> T
where
T: TypeFoldable<'tcx>,
{
self.inh.normalize_associated_types_in_with_cause(
- ObligationCause::new(span, self.body_id, ObligationCauseCode::WellFormed(Some(hir_id))),
+ ObligationCause::new(span, self.body_id, ObligationCauseCode::WellFormed(Some(loc))),
self.param_env,
value,
)
use rustc_infer::infer;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
-use rustc_middle::hir::map::blocks::FnLikeNode;
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::{self, Const, Ty, TyCtxt};
}
fn default_constness_for_trait_bounds(&self) -> hir::Constness {
- // FIXME: refactor this into a method
- let node = self.tcx.hir().get(self.body_id);
- if let Some(fn_like) = FnLikeNode::from_node(node) {
- fn_like.constness()
- } else {
- hir::Constness::NotConst
- }
+ self.tcx.hir().get(self.body_id).constness()
}
fn get_type_parameter_bounds(
use rustc_hir::PatKind;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_middle::ty::Ty;
-use rustc_span::{sym, Span};
+use rustc_span::Span;
use rustc_trait_selection::traits;
pub(super) struct GatherLocalsVisitor<'a, 'tcx> {
fcx: &'a FnCtxt<'a, 'tcx>,
- parent_id: hir::HirId,
// parameters are special cases of patterns, but we want to handle them as
// *distinct* cases. so track when we are hitting a pattern *within* an fn
// parameter.
}
impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
- pub(super) fn new(fcx: &'a FnCtxt<'a, 'tcx>, parent_id: hir::HirId) -> Self {
- Self { fcx, parent_id, outermost_fn_param_pat: None }
+ pub(super) fn new(fcx: &'a FnCtxt<'a, 'tcx>) -> Self {
+ Self { fcx, outermost_fn_param_pat: None }
}
fn assign(&mut self, span: Span, nid: hir::HirId, ty_opt: Option<LocalTy<'tcx>>) -> Ty<'tcx> {
Some(ref ty) => {
let o_ty = self.fcx.to_ty(&ty);
- let revealed_ty = self.fcx.instantiate_opaque_types_from_value(
- self.parent_id,
- o_ty,
- ty.span,
- Some(sym::impl_trait_in_bindings),
- );
-
- let c_ty =
- self.fcx.inh.infcx.canonicalize_user_type_annotation(UserType::Ty(revealed_ty));
- debug!(
- "visit_local: ty.hir_id={:?} o_ty={:?} revealed_ty={:?} c_ty={:?}",
- ty.hir_id, o_ty, revealed_ty, c_ty
- );
+ let c_ty = self.fcx.inh.infcx.canonicalize_user_type_annotation(UserType::Ty(o_ty));
+ debug!("visit_local: ty.hir_id={:?} o_ty={:?} c_ty={:?}", ty.hir_id, o_ty, c_ty);
self.fcx
.typeck_results
.borrow_mut()
.user_provided_types_mut()
.insert(ty.hir_id, c_ty);
- Some(LocalTy { decl_ty: o_ty, revealed_ty })
+ Some(LocalTy { decl_ty: o_ty, revealed_ty: o_ty })
}
None => None,
};
item_name
);
err.span_label(item_name.span, &format!("private {}", kind));
+ let sp = self
+ .tcx
+ .hir()
+ .span_if_local(def_id)
+ .unwrap_or_else(|| self.tcx.def_span(def_id));
+ err.span_label(sp, &format!("private {} defined here", kind));
self.suggest_valid_traits(&mut err, out_of_scope_traits);
err.emit();
}
use rustc_session::config;
use rustc_session::parse::feature_err;
use rustc_session::Session;
+use rustc_span::source_map::DUMMY_SP;
use rustc_span::symbol::{kw, Ident};
use rustc_span::{self, BytePos, MultiSpan, Span};
-use rustc_span::{source_map::DUMMY_SP, sym};
use rustc_target::abi::VariantIdx;
use rustc_target::spec::abi::Abi;
use rustc_trait_selection::traits;
let expected_type = fcx.normalize_associated_types_in(body.value.span, expected_type);
fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
- let revealed_ty = fcx.instantiate_opaque_types_from_value(
- id,
- expected_type,
- body.value.span,
- Some(sym::impl_trait_in_bindings),
- );
-
// Gather locals in statics (because of block expressions).
- GatherLocalsVisitor::new(&fcx, id).visit_body(body);
+ GatherLocalsVisitor::new(&fcx).visit_body(body);
- fcx.check_expr_coercable_to_type(&body.value, revealed_ty, None);
+ fcx.check_expr_coercable_to_type(&body.value, expected_type, None);
- fcx.write_ty(id, revealed_ty);
+ fcx.write_ty(id, expected_type);
fcx
};
})
}
-/// Emit an error for recursive opaque types in a `let` binding.
-fn binding_opaque_type_cycle_error(
- tcx: TyCtxt<'tcx>,
- def_id: LocalDefId,
- span: Span,
- partially_expanded_type: Ty<'tcx>,
-) {
- let mut err = struct_span_err!(tcx.sess, span, E0720, "cannot resolve opaque type");
- err.span_label(span, "cannot resolve opaque type");
- // Find the owner that declared this `impl Trait` type.
- let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
- let mut prev_hir_id = hir_id;
- let mut hir_id = tcx.hir().get_parent_node(hir_id);
- while let Some(node) = tcx.hir().find(hir_id) {
- match node {
- hir::Node::Local(hir::Local {
- pat,
- init: None,
- ty: Some(ty),
- source: hir::LocalSource::Normal,
- ..
- }) => {
- err.span_label(pat.span, "this binding might not have a concrete type");
- err.span_suggestion_verbose(
- ty.span.shrink_to_hi(),
- "set the binding to a value for a concrete type to be resolved",
- " = /* value */".to_string(),
- Applicability::HasPlaceholders,
- );
- }
- hir::Node::Local(hir::Local {
- init: Some(expr),
- source: hir::LocalSource::Normal,
- ..
- }) => {
- let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
- let typeck_results =
- tcx.typeck(tcx.hir().local_def_id(tcx.hir().get_parent_item(hir_id)));
- if let Some(ty) = typeck_results.node_type_opt(expr.hir_id) {
- err.span_label(
- expr.span,
- &format!(
- "this is of type `{}`, which doesn't constrain \
- `{}` enough to arrive to a concrete type",
- ty, partially_expanded_type
- ),
- );
- }
- }
- _ => {}
- }
- if prev_hir_id == hir_id {
- break;
- }
- prev_hir_id = hir_id;
- hir_id = tcx.hir().get_parent_node(hir_id);
- }
- err.emit();
-}
-
// Forbid defining intrinsics in Rust code,
// as they must always be defined by the compiler.
fn fn_maybe_err(tcx: TyCtxt<'_>, sp: Span, abi: Abi) {
use rustc_span::Span;
use rustc_trait_selection::opaque_types::may_define_opaque_type;
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
-use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode};
+use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode, WellFormedLoc};
+use std::convert::TryInto;
use std::iter;
use std::ops::ControlFlow;
span: Span,
sig_if_method: Option<&hir::FnSig<'_>>,
) {
- let code = ObligationCauseCode::WellFormed(Some(item_id));
+ let code = ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(item_id.expect_owner())));
for_id(tcx, item_id, span).with_fcx(|fcx| {
let item = fcx.tcx.associated_item(fcx.tcx.hir().local_def_id(item_id));
match item.kind {
ty::AssocKind::Const => {
let ty = fcx.tcx.type_of(item.def_id);
- let ty = fcx.normalize_associated_types_in_wf(span, ty, item_id);
+ let ty = fcx.normalize_associated_types_in_wf(
+ span,
+ ty,
+ WellFormedLoc::Ty(item_id.expect_owner()),
+ );
fcx.register_wf_obligation(ty.into(), span, code.clone());
}
ty::AssocKind::Fn => {
}
if item.defaultness.has_value() {
let ty = fcx.tcx.type_of(item.def_id);
- let ty = fcx.normalize_associated_types_in_wf(span, ty, item_id);
+ let ty = fcx.normalize_associated_types_in_wf(
+ span,
+ ty,
+ WellFormedLoc::Ty(item_id.expect_owner()),
+ );
fcx.register_wf_obligation(ty.into(), span, code.clone());
}
}
for_id(tcx, item_id, ty_span).with_fcx(|fcx| {
let ty = tcx.type_of(tcx.hir().local_def_id(item_id));
- let item_ty = fcx.normalize_associated_types_in_wf(ty_span, ty, item_id);
+ let item_ty = fcx.normalize_associated_types_in_wf(
+ ty_span,
+ ty,
+ WellFormedLoc::Ty(item_id.expect_owner()),
+ );
let mut forbid_unsized = true;
if allow_foreign_ty {
fcx.register_wf_obligation(
item_ty.into(),
ty_span,
- ObligationCauseCode::WellFormed(Some(item_id)),
+ ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(item_id.expect_owner()))),
);
if forbid_unsized {
fcx.register_bound(
fcx.register_wf_obligation(
self_ty.into(),
ast_self_ty.span,
- ObligationCauseCode::WellFormed(Some(item.hir_id())),
+ ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(
+ item.hir_id().expect_owner(),
+ ))),
);
}
}
implied_bounds: &mut Vec<Ty<'tcx>>,
) {
let sig = fcx.tcx.liberate_late_bound_regions(def_id, sig);
- let sig = fcx.normalize_associated_types_in(span, sig);
- for (&input_ty, ty) in iter::zip(sig.inputs(), hir_decl.inputs) {
- fcx.register_wf_obligation(input_ty.into(), ty.span, ObligationCauseCode::WellFormed(None));
+ // Normalize the input and output types one at a time, using a different
+ // `WellFormedLoc` for each. We cannot call `normalize_associated_types`
+ // on the entire `FnSig`, since this would use the same `WellFormedLoc`
+ // for each type, preventing the HIR wf check from generating
+ // a nice error message.
+ let ty::FnSig { mut inputs_and_output, c_variadic, unsafety, abi } = sig;
+ inputs_and_output =
+ fcx.tcx.mk_type_list(inputs_and_output.iter().enumerate().map(|(i, ty)| {
+ fcx.normalize_associated_types_in_wf(
+ span,
+ ty,
+ WellFormedLoc::Param {
+ function: def_id.expect_local(),
+ // Note that the `param_idx` of the output type is
+ // one greater than the index of the last input type.
+ param_idx: i.try_into().unwrap(),
+ },
+ )
+ }));
+ // Manually call `normalize_assocaited_types_in` on the other types
+ // in `FnSig`. This ensures that if the types of these fields
+ // ever change to include projections, we will start normalizing
+ // them automatically.
+ let sig = ty::FnSig {
+ inputs_and_output,
+ c_variadic: fcx.normalize_associated_types_in(span, c_variadic),
+ unsafety: fcx.normalize_associated_types_in(span, unsafety),
+ abi: fcx.normalize_associated_types_in(span, abi),
+ };
+
+ for (i, (&input_ty, ty)) in iter::zip(sig.inputs(), hir_decl.inputs).enumerate() {
+ fcx.register_wf_obligation(
+ input_ty.into(),
+ ty.span,
+ ObligationCauseCode::WellFormed(Some(WellFormedLoc::Param {
+ function: def_id.expect_local(),
+ param_idx: i.try_into().unwrap(),
+ })),
+ );
}
+
implied_bounds.extend(sig.inputs());
fcx.register_wf_obligation(
let mut skip_add = false;
if let ty::Opaque(definition_ty_def_id, _substs) = *definition_ty.kind() {
- if let hir::OpaqueTyOrigin::Misc | hir::OpaqueTyOrigin::TyAlias = opaque_defn.origin
- {
+ if opaque_defn.origin == hir::OpaqueTyOrigin::TyAlias {
if opaque_type_key.def_id == definition_ty_def_id {
debug!(
"skipping adding concrete definition for opaque type {:?} {:?}",
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
use rustc_hir::weak_lang_items;
use rustc_hir::{GenericParamKind, HirId, Node};
-use rustc_middle::hir::map::blocks::FnLikeNode;
use rustc_middle::hir::map::Map;
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
use rustc_middle::mir::mono::Linkage;
}
fn default_constness_for_trait_bounds(&self) -> hir::Constness {
- if let Some(fn_like) = FnLikeNode::from_node(self.node()) {
- fn_like.constness()
- } else {
- hir::Constness::NotConst
- }
+ self.node().constness()
}
fn get_type_parameter_bounds(
let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
tcx.mk_adt(def, substs)
}
- ItemKind::OpaqueTy(OpaqueTy { origin: hir::OpaqueTyOrigin::Binding, .. }) => {
- let_position_impl_trait_type(tcx, def_id)
- }
ItemKind::OpaqueTy(OpaqueTy { impl_trait_fn: None, .. }) => {
find_opaque_ty_constraints(tcx, def_id)
}
}
}
-/// Retrieve the inferred concrete type for let position impl trait.
-///
-/// This is different to other kinds of impl trait because:
-///
-/// 1. We know which function contains the defining use (the function that
-/// contains the let statement)
-/// 2. We do not currently allow (free) lifetimes in the return type. `let`
-/// statements in some statically unreachable code are removed from the MIR
-/// by the time we borrow check, and it's not clear how we should handle
-/// those.
-fn let_position_impl_trait_type(tcx: TyCtxt<'_>, opaque_ty_id: LocalDefId) -> Ty<'_> {
- let scope = tcx.hir().get_defining_scope(tcx.hir().local_def_id_to_hir_id(opaque_ty_id));
- let scope_def_id = tcx.hir().local_def_id(scope);
-
- let opaque_ty_def_id = opaque_ty_id.to_def_id();
-
- let owner_typeck_results = tcx.typeck(scope_def_id);
- let concrete_ty = owner_typeck_results
- .concrete_opaque_types
- .get_by(|(key, _)| key.def_id == opaque_ty_def_id)
- .map(|concrete_ty| *concrete_ty)
- .unwrap_or_else(|| {
- tcx.sess.delay_span_bug(
- DUMMY_SP,
- &format!(
- "owner {:?} has no opaque type for {:?} in its typeck results",
- scope_def_id, opaque_ty_id
- ),
- );
- if let Some(ErrorReported) = owner_typeck_results.tainted_by_errors {
- // Some error in the owner fn prevented us from populating the
- // `concrete_opaque_types` table.
- tcx.ty_error()
- } else {
- // We failed to resolve the opaque type or it resolves to
- // itself. Return the non-revealed type, which should result in
- // E0720.
- tcx.mk_opaque(
- opaque_ty_def_id,
- InternalSubsts::identity_for_item(tcx, opaque_ty_def_id),
- )
- }
- });
- debug!("concrete_ty = {:?}", concrete_ty);
- if concrete_ty.has_erased_regions() {
- // FIXME(impl_trait_in_bindings) Handle this case.
- tcx.sess.span_fatal(
- tcx.hir().span(tcx.hir().local_def_id_to_hir_id(opaque_ty_id)),
- "lifetimes in impl Trait types in bindings are not currently supported",
- );
- }
- concrete_ty
-}
-
fn infer_placeholder_type<'a>(
tcx: TyCtxt<'a>,
def_id: LocalDefId,
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
use rustc_hir::HirId;
use rustc_infer::infer::TyCtxtInferExt;
-use rustc_infer::traits::ObligationCause;
use rustc_infer::traits::TraitEngine;
+use rustc_infer::traits::{ObligationCause, WellFormedLoc};
use rustc_middle::ty::query::Providers;
-use rustc_middle::ty::{self, ToPredicate, TyCtxt};
+use rustc_middle::ty::{self, Region, ToPredicate, TyCtxt, TypeFoldable, TypeFolder};
use rustc_trait_selection::traits;
pub fn provide(providers: &mut Providers) {
// need access to `ItemCtxt`
fn diagnostic_hir_wf_check<'tcx>(
tcx: TyCtxt<'tcx>,
- (predicate, hir_id): (ty::Predicate<'tcx>, HirId),
+ (predicate, loc): (ty::Predicate<'tcx>, WellFormedLoc),
) -> Option<ObligationCause<'tcx>> {
let hir = tcx.hir();
- // HIR wfcheck should only ever happen as part of improving an existing error
- tcx.sess.delay_span_bug(hir.span(hir_id), "Performed HIR wfcheck without an existing error!");
- // Currently, we only handle WF checking for items (e.g. associated items).
- // It would be nice to extend this to handle wf checks inside functions.
- let def_id = match tcx.hir().opt_local_def_id(hir_id) {
- Some(def_id) => def_id,
- None => return None,
+ let def_id = match loc {
+ WellFormedLoc::Ty(def_id) => def_id,
+ WellFormedLoc::Param { function, param_idx: _ } => function,
};
+ let hir_id = HirId::make_owner(def_id);
+
+ // HIR wfcheck should only ever happen as part of improving an existing error
+ tcx.sess
+ .delay_span_bug(tcx.def_span(def_id), "Performed HIR wfcheck without an existing error!");
- // FIXME - figure out how we want to handle wf-checking for
- // things inside a function body.
let icx = ItemCtxt::new(tcx, def_id.to_def_id());
// To perform HIR-based WF checking, we iterate over all HIR types
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
self.tcx.infer_ctxt().enter(|infcx| {
let mut fulfill = traits::FulfillmentContext::new();
- let tcx_ty = self.icx.to_ty(ty);
+ let tcx_ty =
+ self.icx.to_ty(ty).fold_with(&mut EraseAllBoundRegions { tcx: self.tcx });
let cause = traits::ObligationCause::new(
ty.span,
self.hir_id,
depth: 0,
};
- let ty = match tcx.hir().get(hir_id) {
- hir::Node::ImplItem(item) => match item.kind {
- hir::ImplItemKind::TyAlias(ty) => Some(ty),
- _ => None,
- },
- hir::Node::TraitItem(item) => match item.kind {
- hir::TraitItemKind::Type(_, ty) => ty,
- _ => None,
+ // Get the starting `hir::Ty` using our `WellFormedLoc`.
+ // We will walk 'into' this type to try to find
+ // a more precise span for our predicate.
+ let ty = match loc {
+ WellFormedLoc::Ty(_) => match hir.get(hir_id) {
+ hir::Node::ImplItem(item) => match item.kind {
+ hir::ImplItemKind::TyAlias(ty) => Some(ty),
+ ref item => bug!("Unexpected ImplItem {:?}", item),
+ },
+ hir::Node::TraitItem(item) => match item.kind {
+ hir::TraitItemKind::Type(_, ty) => ty,
+ ref item => bug!("Unexpected TraitItem {:?}", item),
+ },
+ hir::Node::Item(item) => match item.kind {
+ hir::ItemKind::Static(ty, _, _) | hir::ItemKind::Const(ty, _) => Some(ty),
+ hir::ItemKind::Impl(ref impl_) => {
+ assert!(impl_.of_trait.is_none(), "Unexpected trait impl: {:?}", impl_);
+ Some(impl_.self_ty)
+ }
+ ref item => bug!("Unexpected item {:?}", item),
+ },
+ ref node => bug!("Unexpected node {:?}", node),
},
- _ => None,
+ WellFormedLoc::Param { function: _, param_idx } => {
+ let fn_decl = hir.fn_decl_by_hir_id(hir_id).unwrap();
+ // Get return type
+ if param_idx as usize == fn_decl.inputs.len() {
+ match fn_decl.output {
+ hir::FnRetTy::Return(ty) => Some(ty),
+ // The unit type `()` is always well-formed
+ hir::FnRetTy::DefaultReturn(_span) => None,
+ }
+ } else {
+ Some(&fn_decl.inputs[param_idx as usize])
+ }
+ }
};
if let Some(ty) = ty {
visitor.visit_ty(ty);
}
visitor.cause
}
+
+struct EraseAllBoundRegions<'tcx> {
+ tcx: TyCtxt<'tcx>,
+}
+
+// Higher ranked regions are complicated.
+// To make matters worse, the HIR WF check can instantiate them
+// outside of a `Binder`, due to the way we (ab)use
+// `ItemCtxt::to_ty`. To make things simpler, we just erase all
+// of them, regardless of depth. At worse, this will give
+// us an inaccurate span for an error message, but cannot
+// lead to unsoundess (we call `delay_span_bug` at the start
+// of `diagnostic_hir_wf_check`).
+impl<'tcx> TypeFolder<'tcx> for EraseAllBoundRegions<'tcx> {
+ fn tcx<'a>(&'a self) -> TyCtxt<'tcx> {
+ self.tcx
+ }
+ fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> {
+ if let ty::ReLateBound(..) = r { &ty::ReErased } else { r }
+ }
+}
///
/// # Example
///
-/// ```no_run
-/// use std::alloc::{GlobalAlloc, Layout, alloc};
+/// ```
+/// use std::alloc::{GlobalAlloc, Layout};
+/// use std::cell::UnsafeCell;
/// use std::ptr::null_mut;
+/// use std::sync::atomic::{
+/// AtomicUsize,
+/// Ordering::{Acquire, SeqCst},
+/// };
///
-/// struct MyAllocator;
-///
-/// unsafe impl GlobalAlloc for MyAllocator {
-/// unsafe fn alloc(&self, _layout: Layout) -> *mut u8 { null_mut() }
-/// unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {}
+/// const ARENA_SIZE: usize = 128 * 1024;
+/// const MAX_SUPPORTED_ALIGN: usize = 4096;
+/// #[repr(C, align(4096))] // 4096 == MAX_SUPPORTED_ALIGN
+/// struct SimpleAllocator {
+/// arena: UnsafeCell<[u8; ARENA_SIZE]>,
+/// remaining: AtomicUsize, // we allocate from the top, counting down
/// }
///
/// #[global_allocator]
-/// static A: MyAllocator = MyAllocator;
+/// static ALLOCATOR: SimpleAllocator = SimpleAllocator {
+/// arena: UnsafeCell::new([0x55; ARENA_SIZE]),
+/// remaining: AtomicUsize::new(ARENA_SIZE),
+/// };
///
-/// fn main() {
-/// unsafe {
-/// assert!(alloc(Layout::new::<u32>()).is_null())
+/// unsafe impl Sync for SimpleAllocator {}
+///
+/// unsafe impl GlobalAlloc for SimpleAllocator {
+/// unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
+/// let size = layout.size();
+/// let align = layout.align();
+///
+/// // `Layout` contract forbids making a `Layout` with align=0, or align not power of 2.
+/// // So we can safely use a mask to ensure alignment without worrying about UB.
+/// let align_mask_to_round_down = !(align - 1);
+///
+/// if align > MAX_SUPPORTED_ALIGN {
+/// return null_mut();
+/// }
+///
+/// let mut allocated = 0;
+/// if self
+/// .remaining
+/// .fetch_update(SeqCst, SeqCst, |mut remaining| {
+/// if size > remaining {
+/// return None;
+/// }
+/// remaining -= size;
+/// remaining &= align_mask_to_round_down;
+/// allocated = remaining;
+/// Some(remaining)
+/// })
+/// .is_err()
+/// {
+/// return null_mut();
+/// };
+/// (self.arena.get() as *mut u8).add(allocated)
/// }
+/// unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {}
+/// }
+///
+/// fn main() {
+/// let _s = format!("allocating a string!");
+/// let currently = ALLOCATOR.remaining.load(Acquire);
+/// println!("allocated so far: {}", ARENA_SIZE - currently);
/// }
/// ```
///
use crate::fmt;
-use crate::iter::{DoubleEndedIterator, Fuse, FusedIterator, Iterator, Map};
+use crate::iter::{DoubleEndedIterator, Fuse, FusedIterator, Iterator, Map, TrustedLen};
use crate::ops::Try;
/// An iterator that maps each element to an iterator, and yields the elements
{
}
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<T, I, F, const N: usize> TrustedLen for FlatMap<I, [T; N], F>
+where
+ I: TrustedLen,
+ F: FnMut(I::Item) -> [T; N],
+{
+}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<'a, T, I, F, const N: usize> TrustedLen for FlatMap<I, &'a [T; N], F>
+where
+ I: TrustedLen,
+ F: FnMut(I::Item) -> &'a [T; N],
+{
+}
+
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<'a, T, I, F, const N: usize> TrustedLen for FlatMap<I, &'a mut [T; N], F>
+where
+ I: TrustedLen,
+ F: FnMut(I::Item) -> &'a mut [T; N],
+{
+}
+
/// An iterator that flattens one level of nesting in an iterator of things
/// that can be turned into iterators.
///
{
}
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<I> TrustedLen for Flatten<I>
+where
+ I: TrustedLen,
+ <I as Iterator>::Item: TrustedConstSize,
+{
+}
+
/// Real logic of both `Flatten` and `FlatMap` which simply delegate to
/// this type.
#[derive(Clone, Debug)]
let (flo, fhi) = self.frontiter.as_ref().map_or((0, Some(0)), U::size_hint);
let (blo, bhi) = self.backiter.as_ref().map_or((0, Some(0)), U::size_hint);
let lo = flo.saturating_add(blo);
+
+ if let Some(fixed_size) = <<I as Iterator>::Item as ConstSizeIntoIterator>::size() {
+ let (lower, upper) = self.iter.size_hint();
+
+ let lower = lower.saturating_mul(fixed_size).saturating_add(lo);
+ let upper =
+ try { fhi?.checked_add(bhi?)?.checked_add(fixed_size.checked_mul(upper?)?)? };
+
+ return (lower, upper);
+ }
+
match (self.iter.size_hint(), fhi, bhi) {
((0, Some(0)), Some(a), Some(b)) => (lo, a.checked_add(b)),
_ => (lo, None),
init
}
}
+
+trait ConstSizeIntoIterator: IntoIterator {
+ // FIXME(#31844): convert to an associated const once specialization supports that
+ fn size() -> Option<usize>;
+}
+
+impl<T> ConstSizeIntoIterator for T
+where
+ T: IntoIterator,
+{
+ #[inline]
+ default fn size() -> Option<usize> {
+ None
+ }
+}
+
+impl<T, const N: usize> ConstSizeIntoIterator for [T; N] {
+ #[inline]
+ fn size() -> Option<usize> {
+ Some(N)
+ }
+}
+
+impl<T, const N: usize> ConstSizeIntoIterator for &[T; N] {
+ #[inline]
+ fn size() -> Option<usize> {
+ Some(N)
+ }
+}
+
+impl<T, const N: usize> ConstSizeIntoIterator for &mut [T; N] {
+ #[inline]
+ fn size() -> Option<usize> {
+ Some(N)
+ }
+}
+
+#[doc(hidden)]
+#[unstable(feature = "std_internals", issue = "none")]
+// FIXME(#20400): Instead of this helper trait there should be multiple impl TrustedLen for Flatten<>
+// blocks with different bounds on Iterator::Item but the compiler erroneously considers them overlapping
+pub unsafe trait TrustedConstSize: IntoIterator {}
+
+#[unstable(feature = "std_internals", issue = "none")]
+unsafe impl<T, const N: usize> TrustedConstSize for [T; N] {}
+#[unstable(feature = "std_internals", issue = "none")]
+unsafe impl<T, const N: usize> TrustedConstSize for &'_ [T; N] {}
+#[unstable(feature = "std_internals", issue = "none")]
+unsafe impl<T, const N: usize> TrustedConstSize for &'_ mut [T; N] {}
use super::*;
+use core::array;
use core::iter::*;
#[test]
assert_eq!(it.next(), None);
assert_eq!(it.next_back(), None);
}
+
+#[test]
+fn test_trusted_len_flatten() {
+ fn assert_trusted_len<T: TrustedLen>(_: &T) {}
+ let mut iter = array::IntoIter::new([[0; 3]; 4]).flatten();
+ assert_trusted_len(&iter);
+
+ assert_eq!(iter.size_hint(), (12, Some(12)));
+ iter.next();
+ assert_eq!(iter.size_hint(), (11, Some(11)));
+ iter.next_back();
+ assert_eq!(iter.size_hint(), (10, Some(10)));
+
+ let iter = array::IntoIter::new([[(); usize::MAX]; 1]).flatten();
+ assert_eq!(iter.size_hint(), (usize::MAX, Some(usize::MAX)));
+
+ let iter = array::IntoIter::new([[(); usize::MAX]; 2]).flatten();
+ assert_eq!(iter.size_hint(), (usize::MAX, None));
+
+ let mut a = [(); 10];
+ let mut b = [(); 10];
+
+ let iter = array::IntoIter::new([&mut a, &mut b]).flatten();
+ assert_trusted_len(&iter);
+ assert_eq!(iter.size_hint(), (20, Some(20)));
+ core::mem::drop(iter);
+
+ let iter = array::IntoIter::new([&a, &b]).flatten();
+ assert_trusted_len(&iter);
+ assert_eq!(iter.size_hint(), (20, Some(20)));
+
+ let iter = [(), (), ()].iter().flat_map(|_| [(); 1000]);
+ assert_trusted_len(&iter);
+ assert_eq!(iter.size_hint(), (3000, Some(3000)));
+
+ let iter = [(), ()].iter().flat_map(|_| &a);
+ assert_trusted_len(&iter);
+ assert_eq!(iter.size_hint(), (20, Some(20)));
+}
use crate::cell::{Cell, RefCell};
use crate::fmt;
-use crate::io::{self, BufReader, Initializer, IoSlice, IoSliceMut, LineWriter};
+use crate::io::{self, BufReader, Initializer, IoSlice, IoSliceMut, LineWriter, Lines, Split};
use crate::lazy::SyncOnceCell;
use crate::pin::Pin;
use crate::sync::atomic::{AtomicBool, Ordering};
pub fn into_locked(self) -> StdinLock<'static> {
self.lock_any()
}
+
+ /// Consumes this handle and returns an iterator over input lines.
+ ///
+ /// For detailed semantics of this method, see the documentation on
+ /// [`BufRead::lines`].
+ ///
+ /// # Examples
+ ///
+ /// ```no_run
+ /// #![feature(stdin_forwarders)]
+ /// use std::io;
+ ///
+ /// let lines = io::stdin().lines();
+ /// for line in lines {
+ /// println!("got a line: {}", line.unwrap());
+ /// }
+ /// ```
+ #[unstable(feature = "stdin_forwarders", issue = "87096")]
+ pub fn lines(self) -> Lines<StdinLock<'static>> {
+ self.into_locked().lines()
+ }
+
+ /// Consumes this handle and returns an iterator over input bytes,
+ /// split at the specified byte value.
+ ///
+ /// For detailed semantics of this method, see the documentation on
+ /// [`BufRead::split`].
+ ///
+ /// # Examples
+ ///
+ /// ```no_run
+ /// #![feature(stdin_forwarders)]
+ /// use std::io;
+ ///
+ /// let splits = io::stdin().split(b'-');
+ /// for split in splits {
+ /// println!("got a chunk: {}", String::from_utf8_lossy(&split.unwrap()));
+ /// }
+ /// ```
+ #[unstable(feature = "stdin_forwarders", issue = "87096")]
+ pub fn split(self, byte: u8) -> Split<StdinLock<'static>> {
+ self.into_locked().split(byte)
+ }
}
#[stable(feature = "std_debug", since = "1.16.0")]
use crate::ptr;
use crate::sync::atomic::{AtomicIsize, AtomicPtr, Ordering};
+ // The system-provided argc and argv, which we store in static memory
+ // here so that we can defer the work of parsing them until its actually
+ // needed.
+ //
+ // Note that we never mutate argv/argc, the argv array, or the argv
+ // strings, which allows the code in this file to be very simple.
static ARGC: AtomicIsize = AtomicIsize::new(0);
static ARGV: AtomicPtr<*const u8> = AtomicPtr::new(ptr::null_mut());
unsafe fn really_init(argc: isize, argv: *const *const u8) {
+ // These don't need to be ordered with each other or other stores,
+ // because they only hold the unmodified system-provide argv/argc.
ARGC.store(argc, Ordering::Relaxed);
ARGV.store(argv as *mut _, Ordering::Relaxed);
}
fn clone() -> Vec<OsString> {
unsafe {
- // Load ARGC and ARGV without a lock. If the store to either ARGV or
- // ARGC isn't visible yet, we'll return an empty argument list.
+ // Load ARGC and ARGV, which hold the unmodified system-provided
+ // argc/argv, so we can read the pointed-to memory without atomics
+ // or synchronization.
+ //
+ // If either ARGC or ARGV is still zero or null, then either there
+ // really are no arguments, or someone is asking for `args()`
+ // before initialization has completed, and we return an empty
+ // list.
let argv = ARGV.load(Ordering::Relaxed);
let argc = if argv.is_null() { 0 } else { ARGC.load(Ordering::Relaxed) };
(0..argc)
+++ /dev/null
-[package]
-authors = ["The Rust Project Developers"]
-name = "term"
-version = "0.0.0"
-edition = "2018"
-
-[dependencies]
-core = { path = "../core" }
-std = { path = "../std" }
+++ /dev/null
-//! Terminal formatting library.
-//!
-//! This crate provides the `Terminal` trait, which abstracts over an [ANSI
-//! Terminal][ansi] to provide color printing, among other things. There are two
-//! implementations, the `TerminfoTerminal`, which uses control characters from
-//! a [terminfo][ti] database, and `WinConsole`, which uses the [Win32 Console
-//! API][win].
-//!
-//! # Examples
-//!
-//! ```no_run
-//! # #![feature(rustc_private)]
-//! extern crate term;
-//! use std::io::prelude::*;
-//!
-//! fn main() {
-//! let mut t = term::stdout().unwrap();
-//!
-//! t.fg(term::color::GREEN).unwrap();
-//! write!(t, "hello, ").unwrap();
-//!
-//! t.fg(term::color::RED).unwrap();
-//! writeln!(t, "world!").unwrap();
-//!
-//! assert!(t.reset().unwrap());
-//! }
-//! ```
-//!
-//! [ansi]: https://en.wikipedia.org/wiki/ANSI_escape_code
-//! [win]: https://docs.microsoft.com/en-us/windows/console/character-mode-applications
-//! [ti]: https://en.wikipedia.org/wiki/Terminfo
-
-#![doc(html_playground_url = "https://play.rust-lang.org/", test(attr(deny(warnings))))]
-#![deny(missing_docs)]
-#![cfg_attr(windows, feature(libc))]
-
-use std::io::prelude::*;
-use std::io::{self, Stderr, Stdout};
-
-pub use terminfo::TerminfoTerminal;
-#[cfg(windows)]
-pub use win::WinConsole;
-
-pub mod terminfo;
-
-#[cfg(windows)]
-mod win;
-
-/// Alias for stdout terminals.
-pub type StdoutTerminal = dyn Terminal<Output = Stdout> + Send;
-/// Alias for stderr terminals.
-pub type StderrTerminal = dyn Terminal<Output = Stderr> + Send;
-
-#[cfg(not(windows))]
-/// Returns a Terminal wrapping stdout, or None if a terminal couldn't be
-/// opened.
-pub fn stdout() -> Option<Box<StdoutTerminal>> {
- TerminfoTerminal::new(io::stdout()).map(|t| Box::new(t) as Box<StdoutTerminal>)
-}
-
-#[cfg(windows)]
-/// Returns a Terminal wrapping stdout, or None if a terminal couldn't be
-/// opened.
-pub fn stdout() -> Option<Box<StdoutTerminal>> {
- TerminfoTerminal::new(io::stdout())
- .map(|t| Box::new(t) as Box<StdoutTerminal>)
- .or_else(|| WinConsole::new(io::stdout()).ok().map(|t| Box::new(t) as Box<StdoutTerminal>))
-}
-
-#[cfg(not(windows))]
-/// Returns a Terminal wrapping stderr, or None if a terminal couldn't be
-/// opened.
-pub fn stderr() -> Option<Box<StderrTerminal>> {
- TerminfoTerminal::new(io::stderr()).map(|t| Box::new(t) as Box<StderrTerminal>)
-}
-
-#[cfg(windows)]
-/// Returns a Terminal wrapping stderr, or None if a terminal couldn't be
-/// opened.
-pub fn stderr() -> Option<Box<StderrTerminal>> {
- TerminfoTerminal::new(io::stderr())
- .map(|t| Box::new(t) as Box<StderrTerminal>)
- .or_else(|| WinConsole::new(io::stderr()).ok().map(|t| Box::new(t) as Box<StderrTerminal>))
-}
-
-/// Terminal color definitions
-#[allow(missing_docs)]
-pub mod color {
- /// Number for a terminal color
- pub type Color = u32;
-
- pub const BLACK: Color = 0;
- pub const RED: Color = 1;
- pub const GREEN: Color = 2;
- pub const YELLOW: Color = 3;
- pub const BLUE: Color = 4;
- pub const MAGENTA: Color = 5;
- pub const CYAN: Color = 6;
- pub const WHITE: Color = 7;
-
- pub const BRIGHT_BLACK: Color = 8;
- pub const BRIGHT_RED: Color = 9;
- pub const BRIGHT_GREEN: Color = 10;
- pub const BRIGHT_YELLOW: Color = 11;
- pub const BRIGHT_BLUE: Color = 12;
- pub const BRIGHT_MAGENTA: Color = 13;
- pub const BRIGHT_CYAN: Color = 14;
- pub const BRIGHT_WHITE: Color = 15;
-}
-
-/// Terminal attributes for use with term.attr().
-///
-/// Most attributes can only be turned on and must be turned off with term.reset().
-/// The ones that can be turned off explicitly take a boolean value.
-/// Color is also represented as an attribute for convenience.
-#[derive(Debug, PartialEq, Eq, Copy, Clone)]
-pub enum Attr {
- /// Bold (or possibly bright) mode
- Bold,
- /// Dim mode, also called faint or half-bright. Often not supported
- Dim,
- /// Italics mode. Often not supported
- Italic(bool),
- /// Underline mode
- Underline(bool),
- /// Blink mode
- Blink,
- /// Standout mode. Often implemented as Reverse, sometimes coupled with Bold
- Standout(bool),
- /// Reverse mode, inverts the foreground and background colors
- Reverse,
- /// Secure mode, also called invis mode. Hides the printed text
- Secure,
- /// Convenience attribute to set the foreground color
- ForegroundColor(color::Color),
- /// Convenience attribute to set the background color
- BackgroundColor(color::Color),
-}
-
-/// A terminal with similar capabilities to an ANSI Terminal
-/// (foreground/background colors etc).
-pub trait Terminal: Write {
- /// The terminal's output writer type.
- type Output: Write;
-
- /// Sets the foreground color to the given color.
- ///
- /// If the color is a bright color, but the terminal only supports 8 colors,
- /// the corresponding normal color will be used instead.
- ///
- /// Returns `Ok(true)` if the color was set, `Ok(false)` otherwise, and `Err(e)`
- /// if there was an I/O error.
- fn fg(&mut self, color: color::Color) -> io::Result<bool>;
-
- /// Sets the background color to the given color.
- ///
- /// If the color is a bright color, but the terminal only supports 8 colors,
- /// the corresponding normal color will be used instead.
- ///
- /// Returns `Ok(true)` if the color was set, `Ok(false)` otherwise, and `Err(e)`
- /// if there was an I/O error.
- fn bg(&mut self, color: color::Color) -> io::Result<bool>;
-
- /// Sets the given terminal attribute, if supported. Returns `Ok(true)`
- /// if the attribute was supported, `Ok(false)` otherwise, and `Err(e)` if
- /// there was an I/O error.
- fn attr(&mut self, attr: Attr) -> io::Result<bool>;
-
- /// Returns `true` if the given terminal attribute is supported.
- fn supports_attr(&self, attr: Attr) -> bool;
-
- /// Resets all terminal attributes and colors to their defaults.
- ///
- /// Returns `Ok(true)` if the terminal was reset, `Ok(false)` otherwise, and `Err(e)` if there
- /// was an I/O error.
- ///
- /// *Note: This does not flush.*
- ///
- /// That means the reset command may get buffered so, if you aren't planning on doing anything
- /// else that might flush stdout's buffer (e.g., writing a line of text), you should flush after
- /// calling reset.
- fn reset(&mut self) -> io::Result<bool>;
-
- /// Gets an immutable reference to the stream inside
- fn get_ref(&self) -> &Self::Output;
-
- /// Gets a mutable reference to the stream inside
- fn get_mut(&mut self) -> &mut Self::Output;
-
- /// Returns the contained stream, destroying the `Terminal`
- fn into_inner(self) -> Self::Output
- where
- Self: Sized;
-}
+++ /dev/null
-//! Terminfo database interface.
-
-use std::collections::HashMap;
-use std::env;
-use std::error;
-use std::fmt;
-use std::fs::File;
-use std::io::{self, prelude::*, BufReader};
-use std::path::Path;
-
-use crate::color;
-use crate::Attr;
-use crate::Terminal;
-
-use parm::{expand, Param, Variables};
-use parser::compiled::{msys_terminfo, parse};
-use searcher::get_dbpath_for_term;
-
-/// A parsed terminfo database entry.
-#[derive(Debug)]
-pub struct TermInfo {
- /// Names for the terminal
- pub names: Vec<String>,
- /// Map of capability name to boolean value
- pub bools: HashMap<String, bool>,
- /// Map of capability name to numeric value
- pub numbers: HashMap<String, u32>,
- /// Map of capability name to raw (unexpanded) string
- pub strings: HashMap<String, Vec<u8>>,
-}
-
-/// A terminfo creation error.
-#[derive(Debug)]
-pub enum Error {
- /// TermUnset Indicates that the environment doesn't include enough information to find
- /// the terminfo entry.
- TermUnset,
- /// MalformedTerminfo indicates that parsing the terminfo entry failed.
- MalformedTerminfo(String),
- /// io::Error forwards any io::Errors encountered when finding or reading the terminfo entry.
- IoError(io::Error),
-}
-
-impl error::Error for Error {
- fn source(&self) -> Option<&(dyn error::Error + 'static)> {
- use Error::*;
- match self {
- IoError(e) => Some(e),
- _ => None,
- }
- }
-}
-
-impl fmt::Display for Error {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- use Error::*;
- match *self {
- TermUnset => Ok(()),
- MalformedTerminfo(ref e) => e.fmt(f),
- IoError(ref e) => e.fmt(f),
- }
- }
-}
-
-impl TermInfo {
- /// Creates a TermInfo based on current environment.
- pub fn from_env() -> Result<TermInfo, Error> {
- let term = match env::var("TERM") {
- Ok(name) => TermInfo::from_name(&name),
- Err(..) => return Err(Error::TermUnset),
- };
-
- if term.is_err() && env::var("MSYSCON").map_or(false, |s| "mintty.exe" == s) {
- // msys terminal
- Ok(msys_terminfo())
- } else {
- term
- }
- }
-
- /// Creates a TermInfo for the named terminal.
- pub fn from_name(name: &str) -> Result<TermInfo, Error> {
- get_dbpath_for_term(name)
- .ok_or_else(|| {
- Error::IoError(io::Error::new(io::ErrorKind::NotFound, "terminfo file not found"))
- })
- .and_then(|p| TermInfo::from_path(&(*p)))
- }
-
- /// Parse the given TermInfo.
- pub fn from_path<P: AsRef<Path>>(path: P) -> Result<TermInfo, Error> {
- Self::_from_path(path.as_ref())
- }
- // Keep the metadata small
- fn _from_path(path: &Path) -> Result<TermInfo, Error> {
- let file = File::open(path).map_err(Error::IoError)?;
- let mut reader = BufReader::new(file);
- parse(&mut reader, false).map_err(Error::MalformedTerminfo)
- }
-}
-
-pub mod searcher;
-
-/// TermInfo format parsing.
-pub mod parser {
- //! ncurses-compatible compiled terminfo format parsing (term(5))
- pub mod compiled;
-}
-pub mod parm;
-
-fn cap_for_attr(attr: Attr) -> &'static str {
- match attr {
- Attr::Bold => "bold",
- Attr::Dim => "dim",
- Attr::Italic(true) => "sitm",
- Attr::Italic(false) => "ritm",
- Attr::Underline(true) => "smul",
- Attr::Underline(false) => "rmul",
- Attr::Blink => "blink",
- Attr::Standout(true) => "smso",
- Attr::Standout(false) => "rmso",
- Attr::Reverse => "rev",
- Attr::Secure => "invis",
- Attr::ForegroundColor(_) => "setaf",
- Attr::BackgroundColor(_) => "setab",
- }
-}
-
-/// A Terminal that knows how many colors it supports, with a reference to its
-/// parsed Terminfo database record.
-pub struct TerminfoTerminal<T> {
- num_colors: u32,
- out: T,
- ti: TermInfo,
-}
-
-impl<T: Write + Send> Terminal for TerminfoTerminal<T> {
- type Output = T;
- fn fg(&mut self, color: color::Color) -> io::Result<bool> {
- let color = self.dim_if_necessary(color);
- if self.num_colors > color {
- return self.apply_cap("setaf", &[Param::Number(color as i32)]);
- }
- Ok(false)
- }
-
- fn bg(&mut self, color: color::Color) -> io::Result<bool> {
- let color = self.dim_if_necessary(color);
- if self.num_colors > color {
- return self.apply_cap("setab", &[Param::Number(color as i32)]);
- }
- Ok(false)
- }
-
- fn attr(&mut self, attr: Attr) -> io::Result<bool> {
- match attr {
- Attr::ForegroundColor(c) => self.fg(c),
- Attr::BackgroundColor(c) => self.bg(c),
- _ => self.apply_cap(cap_for_attr(attr), &[]),
- }
- }
-
- fn supports_attr(&self, attr: Attr) -> bool {
- match attr {
- Attr::ForegroundColor(_) | Attr::BackgroundColor(_) => self.num_colors > 0,
- _ => {
- let cap = cap_for_attr(attr);
- self.ti.strings.get(cap).is_some()
- }
- }
- }
-
- fn reset(&mut self) -> io::Result<bool> {
- // are there any terminals that have color/attrs and not sgr0?
- // Try falling back to sgr, then op
- let cmd = match ["sgr0", "sgr", "op"].iter().find_map(|cap| self.ti.strings.get(*cap)) {
- Some(op) => match expand(&op, &[], &mut Variables::new()) {
- Ok(cmd) => cmd,
- Err(e) => return Err(io::Error::new(io::ErrorKind::InvalidData, e)),
- },
- None => return Ok(false),
- };
- self.out.write_all(&cmd).and(Ok(true))
- }
-
- fn get_ref(&self) -> &T {
- &self.out
- }
-
- fn get_mut(&mut self) -> &mut T {
- &mut self.out
- }
-
- fn into_inner(self) -> T
- where
- Self: Sized,
- {
- self.out
- }
-}
-
-impl<T: Write + Send> TerminfoTerminal<T> {
- /// Creates a new TerminfoTerminal with the given TermInfo and Write.
- pub fn new_with_terminfo(out: T, terminfo: TermInfo) -> TerminfoTerminal<T> {
- let nc = if terminfo.strings.contains_key("setaf") && terminfo.strings.contains_key("setab")
- {
- terminfo.numbers.get("colors").map_or(0, |&n| n)
- } else {
- 0
- };
-
- TerminfoTerminal { out, ti: terminfo, num_colors: nc }
- }
-
- /// Creates a new TerminfoTerminal for the current environment with the given Write.
- ///
- /// Returns `None` when the terminfo cannot be found or parsed.
- pub fn new(out: T) -> Option<TerminfoTerminal<T>> {
- TermInfo::from_env().map(move |ti| TerminfoTerminal::new_with_terminfo(out, ti)).ok()
- }
-
- fn dim_if_necessary(&self, color: color::Color) -> color::Color {
- if color >= self.num_colors && color >= 8 && color < 16 { color - 8 } else { color }
- }
-
- fn apply_cap(&mut self, cmd: &str, params: &[Param]) -> io::Result<bool> {
- match self.ti.strings.get(cmd) {
- Some(cmd) => match expand(&cmd, params, &mut Variables::new()) {
- Ok(s) => self.out.write_all(&s).and(Ok(true)),
- Err(e) => Err(io::Error::new(io::ErrorKind::InvalidData, e)),
- },
- None => Ok(false),
- }
- }
-}
-
-impl<T: Write> Write for TerminfoTerminal<T> {
- fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
- self.out.write(buf)
- }
-
- fn flush(&mut self) -> io::Result<()> {
- self.out.flush()
- }
-}
+++ /dev/null
-//! Parameterized string expansion
-
-use self::Param::*;
-use self::States::*;
-
-use std::iter::repeat;
-
-#[cfg(test)]
-mod tests;
-
-#[derive(Clone, Copy, PartialEq)]
-enum States {
- Nothing,
- Percent,
- SetVar,
- GetVar,
- PushParam,
- CharConstant,
- CharClose,
- IntConstant(i32),
- FormatPattern(Flags, FormatState),
- SeekIfElse(usize),
- SeekIfElsePercent(usize),
- SeekIfEnd(usize),
- SeekIfEndPercent(usize),
-}
-
-#[derive(Copy, PartialEq, Clone)]
-enum FormatState {
- Flags,
- Width,
- Precision,
-}
-
-/// Types of parameters a capability can use
-#[allow(missing_docs)]
-#[derive(Clone)]
-pub enum Param {
- Words(String),
- Number(i32),
-}
-
-/// Container for static and dynamic variable arrays
-pub struct Variables {
- /// Static variables A-Z
- sta_va: [Param; 26],
- /// Dynamic variables a-z
- dyn_va: [Param; 26],
-}
-
-impl Variables {
- /// Returns a new zero-initialized Variables
- pub fn new() -> Variables {
- Variables {
- sta_va: [
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- ],
- dyn_va: [
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- ],
- }
- }
-}
-
-/// Expand a parameterized capability
-///
-/// # Arguments
-/// * `cap` - string to expand
-/// * `params` - vector of params for %p1 etc
-/// * `vars` - Variables struct for %Pa etc
-///
-/// To be compatible with ncurses, `vars` should be the same between calls to `expand` for
-/// multiple capabilities for the same terminal.
-pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result<Vec<u8>, String> {
- let mut state = Nothing;
-
- // expanded cap will only rarely be larger than the cap itself
- let mut output = Vec::with_capacity(cap.len());
-
- let mut stack: Vec<Param> = Vec::new();
-
- // Copy parameters into a local vector for mutability
- let mut mparams = [
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- Number(0),
- ];
- for (dst, src) in mparams.iter_mut().zip(params.iter()) {
- *dst = (*src).clone();
- }
-
- for &c in cap.iter() {
- let cur = c as char;
- let mut old_state = state;
- match state {
- Nothing => {
- if cur == '%' {
- state = Percent;
- } else {
- output.push(c);
- }
- }
- Percent => {
- match cur {
- '%' => {
- output.push(c);
- state = Nothing
- }
- 'c' => {
- match stack.pop() {
- // if c is 0, use 0200 (128) for ncurses compatibility
- Some(Number(0)) => output.push(128u8),
- // Don't check bounds. ncurses just casts and truncates.
- Some(Number(c)) => output.push(c as u8),
- Some(_) => return Err("a non-char was used with %c".to_string()),
- None => return Err("stack is empty".to_string()),
- }
- }
- 'p' => state = PushParam,
- 'P' => state = SetVar,
- 'g' => state = GetVar,
- '\'' => state = CharConstant,
- '{' => state = IntConstant(0),
- 'l' => match stack.pop() {
- Some(Words(s)) => stack.push(Number(s.len() as i32)),
- Some(_) => return Err("a non-str was used with %l".to_string()),
- None => return Err("stack is empty".to_string()),
- },
- '+' | '-' | '/' | '*' | '^' | '&' | '|' | 'm' => {
- match (stack.pop(), stack.pop()) {
- (Some(Number(y)), Some(Number(x))) => stack.push(Number(match cur {
- '+' => x + y,
- '-' => x - y,
- '*' => x * y,
- '/' => x / y,
- '|' => x | y,
- '&' => x & y,
- '^' => x ^ y,
- 'm' => x % y,
- _ => unreachable!("All cases handled"),
- })),
- (Some(_), Some(_)) => {
- return Err(format!("non-numbers on stack with {}", cur));
- }
- _ => return Err("stack is empty".to_string()),
- }
- }
- '=' | '>' | '<' | 'A' | 'O' => match (stack.pop(), stack.pop()) {
- (Some(Number(y)), Some(Number(x))) => stack.push(Number(
- if match cur {
- '=' => x == y,
- '<' => x < y,
- '>' => x > y,
- 'A' => x > 0 && y > 0,
- 'O' => x > 0 || y > 0,
- _ => unreachable!(),
- } {
- 1
- } else {
- 0
- },
- )),
- (Some(_), Some(_)) => {
- return Err(format!("non-numbers on stack with {}", cur));
- }
- _ => return Err("stack is empty".to_string()),
- },
- '!' | '~' => match stack.pop() {
- Some(Number(x)) => stack.push(Number(match cur {
- '!' if x > 0 => 0,
- '!' => 1,
- '~' => !x,
- _ => unreachable!(),
- })),
- Some(_) => return Err(format!("non-numbers on stack with {}", cur)),
- None => return Err("stack is empty".to_string()),
- },
- 'i' => match (&mparams[0], &mparams[1]) {
- (&Number(x), &Number(y)) => {
- mparams[0] = Number(x + 1);
- mparams[1] = Number(y + 1);
- }
- _ => return Err("first two params not numbers with %i".to_string()),
- },
-
- // printf-style support for %doxXs
- 'd' | 'o' | 'x' | 'X' | 's' => {
- if let Some(arg) = stack.pop() {
- let flags = Flags::new();
- let res = format(arg, FormatOp::from_char(cur), flags)?;
- output.extend(res.iter().cloned());
- } else {
- return Err("stack is empty".to_string());
- }
- }
- ':' | '#' | ' ' | '.' | '0'..='9' => {
- let mut flags = Flags::new();
- let mut fstate = FormatState::Flags;
- match cur {
- ':' => (),
- '#' => flags.alternate = true,
- ' ' => flags.space = true,
- '.' => fstate = FormatState::Precision,
- '0'..='9' => {
- flags.width = cur as usize - '0' as usize;
- fstate = FormatState::Width;
- }
- _ => unreachable!(),
- }
- state = FormatPattern(flags, fstate);
- }
-
- // conditionals
- '?' => (),
- 't' => match stack.pop() {
- Some(Number(0)) => state = SeekIfElse(0),
- Some(Number(_)) => (),
- Some(_) => return Err("non-number on stack with conditional".to_string()),
- None => return Err("stack is empty".to_string()),
- },
- 'e' => state = SeekIfEnd(0),
- ';' => (),
- _ => return Err(format!("unrecognized format option {}", cur)),
- }
- }
- PushParam => {
- // params are 1-indexed
- stack.push(
- mparams[match cur.to_digit(10) {
- Some(d) => d as usize - 1,
- None => return Err("bad param number".to_string()),
- }]
- .clone(),
- );
- }
- SetVar => {
- if cur >= 'A' && cur <= 'Z' {
- if let Some(arg) = stack.pop() {
- let idx = (cur as u8) - b'A';
- vars.sta_va[idx as usize] = arg;
- } else {
- return Err("stack is empty".to_string());
- }
- } else if cur >= 'a' && cur <= 'z' {
- if let Some(arg) = stack.pop() {
- let idx = (cur as u8) - b'a';
- vars.dyn_va[idx as usize] = arg;
- } else {
- return Err("stack is empty".to_string());
- }
- } else {
- return Err("bad variable name in %P".to_string());
- }
- }
- GetVar => {
- if cur >= 'A' && cur <= 'Z' {
- let idx = (cur as u8) - b'A';
- stack.push(vars.sta_va[idx as usize].clone());
- } else if cur >= 'a' && cur <= 'z' {
- let idx = (cur as u8) - b'a';
- stack.push(vars.dyn_va[idx as usize].clone());
- } else {
- return Err("bad variable name in %g".to_string());
- }
- }
- CharConstant => {
- stack.push(Number(c as i32));
- state = CharClose;
- }
- CharClose => {
- if cur != '\'' {
- return Err("malformed character constant".to_string());
- }
- }
- IntConstant(i) => {
- if cur == '}' {
- stack.push(Number(i));
- state = Nothing;
- } else if let Some(digit) = cur.to_digit(10) {
- match i.checked_mul(10).and_then(|i_ten| i_ten.checked_add(digit as i32)) {
- Some(i) => {
- state = IntConstant(i);
- old_state = Nothing;
- }
- None => return Err("int constant too large".to_string()),
- }
- } else {
- return Err("bad int constant".to_string());
- }
- }
- FormatPattern(ref mut flags, ref mut fstate) => {
- old_state = Nothing;
- match (*fstate, cur) {
- (_, 'd') | (_, 'o') | (_, 'x') | (_, 'X') | (_, 's') => {
- if let Some(arg) = stack.pop() {
- let res = format(arg, FormatOp::from_char(cur), *flags)?;
- output.extend(res.iter().cloned());
- // will cause state to go to Nothing
- old_state = FormatPattern(*flags, *fstate);
- } else {
- return Err("stack is empty".to_string());
- }
- }
- (FormatState::Flags, '#') => {
- flags.alternate = true;
- }
- (FormatState::Flags, '-') => {
- flags.left = true;
- }
- (FormatState::Flags, '+') => {
- flags.sign = true;
- }
- (FormatState::Flags, ' ') => {
- flags.space = true;
- }
- (FormatState::Flags, '0'..='9') => {
- flags.width = cur as usize - '0' as usize;
- *fstate = FormatState::Width;
- }
- (FormatState::Flags, '.') => {
- *fstate = FormatState::Precision;
- }
- (FormatState::Width, '0'..='9') => {
- let old = flags.width;
- flags.width = flags.width * 10 + (cur as usize - '0' as usize);
- if flags.width < old {
- return Err("format width overflow".to_string());
- }
- }
- (FormatState::Width, '.') => {
- *fstate = FormatState::Precision;
- }
- (FormatState::Precision, '0'..='9') => {
- let old = flags.precision;
- flags.precision = flags.precision * 10 + (cur as usize - '0' as usize);
- if flags.precision < old {
- return Err("format precision overflow".to_string());
- }
- }
- _ => return Err("invalid format specifier".to_string()),
- }
- }
- SeekIfElse(level) => {
- if cur == '%' {
- state = SeekIfElsePercent(level);
- }
- old_state = Nothing;
- }
- SeekIfElsePercent(level) => {
- if cur == ';' {
- if level == 0 {
- state = Nothing;
- } else {
- state = SeekIfElse(level - 1);
- }
- } else if cur == 'e' && level == 0 {
- state = Nothing;
- } else if cur == '?' {
- state = SeekIfElse(level + 1);
- } else {
- state = SeekIfElse(level);
- }
- }
- SeekIfEnd(level) => {
- if cur == '%' {
- state = SeekIfEndPercent(level);
- }
- old_state = Nothing;
- }
- SeekIfEndPercent(level) => {
- if cur == ';' {
- if level == 0 {
- state = Nothing;
- } else {
- state = SeekIfEnd(level - 1);
- }
- } else if cur == '?' {
- state = SeekIfEnd(level + 1);
- } else {
- state = SeekIfEnd(level);
- }
- }
- }
- if state == old_state {
- state = Nothing;
- }
- }
- Ok(output)
-}
-
-#[derive(Copy, PartialEq, Clone)]
-struct Flags {
- width: usize,
- precision: usize,
- alternate: bool,
- left: bool,
- sign: bool,
- space: bool,
-}
-
-impl Flags {
- fn new() -> Flags {
- Flags { width: 0, precision: 0, alternate: false, left: false, sign: false, space: false }
- }
-}
-
-#[derive(Copy, Clone)]
-enum FormatOp {
- Digit,
- Octal,
- LowerHex,
- UpperHex,
- String,
-}
-
-impl FormatOp {
- fn from_char(c: char) -> FormatOp {
- match c {
- 'd' => FormatOp::Digit,
- 'o' => FormatOp::Octal,
- 'x' => FormatOp::LowerHex,
- 'X' => FormatOp::UpperHex,
- 's' => FormatOp::String,
- _ => panic!("bad FormatOp char"),
- }
- }
- fn to_char(self) -> char {
- match self {
- FormatOp::Digit => 'd',
- FormatOp::Octal => 'o',
- FormatOp::LowerHex => 'x',
- FormatOp::UpperHex => 'X',
- FormatOp::String => 's',
- }
- }
-}
-
-fn format(val: Param, op: FormatOp, flags: Flags) -> Result<Vec<u8>, String> {
- let mut s = match val {
- Number(d) => {
- match op {
- FormatOp::Digit => {
- if flags.sign {
- format!("{:+01$}", d, flags.precision)
- } else if d < 0 {
- // C doesn't take sign into account in precision calculation.
- format!("{:01$}", d, flags.precision + 1)
- } else if flags.space {
- format!(" {:01$}", d, flags.precision)
- } else {
- format!("{:01$}", d, flags.precision)
- }
- }
- FormatOp::Octal => {
- if flags.alternate {
- // Leading octal zero counts against precision.
- format!("0{:01$o}", d, flags.precision.saturating_sub(1))
- } else {
- format!("{:01$o}", d, flags.precision)
- }
- }
- FormatOp::LowerHex => {
- if flags.alternate && d != 0 {
- format!("0x{:01$x}", d, flags.precision)
- } else {
- format!("{:01$x}", d, flags.precision)
- }
- }
- FormatOp::UpperHex => {
- if flags.alternate && d != 0 {
- format!("0X{:01$X}", d, flags.precision)
- } else {
- format!("{:01$X}", d, flags.precision)
- }
- }
- FormatOp::String => return Err("non-number on stack with %s".to_string()),
- }
- .into_bytes()
- }
- Words(s) => match op {
- FormatOp::String => {
- let mut s = s.into_bytes();
- if flags.precision > 0 && flags.precision < s.len() {
- s.truncate(flags.precision);
- }
- s
- }
- _ => return Err(format!("non-string on stack with %{}", op.to_char())),
- },
- };
- if flags.width > s.len() {
- let n = flags.width - s.len();
- if flags.left {
- s.extend(repeat(b' ').take(n));
- } else {
- let mut s_ = Vec::with_capacity(flags.width);
- s_.extend(repeat(b' ').take(n));
- s_.extend(s.into_iter());
- s = s_;
- }
- }
- Ok(s)
-}
+++ /dev/null
-use super::*;
-
-use std::result::Result::Ok;
-
-#[test]
-fn test_basic_setabf() {
- let s = b"\\E[48;5;%p1%dm";
- assert_eq!(
- expand(s, &[Number(1)], &mut Variables::new()).unwrap(),
- "\\E[48;5;1m".bytes().collect::<Vec<_>>()
- );
-}
-
-#[test]
-fn test_multiple_int_constants() {
- assert_eq!(
- expand(b"%{1}%{2}%d%d", &[], &mut Variables::new()).unwrap(),
- "21".bytes().collect::<Vec<_>>()
- );
-}
-
-#[test]
-fn test_op_i() {
- let mut vars = Variables::new();
- assert_eq!(
- expand(b"%p1%d%p2%d%p3%d%i%p1%d%p2%d%p3%d", &[Number(1), Number(2), Number(3)], &mut vars),
- Ok("123233".bytes().collect::<Vec<_>>())
- );
- assert_eq!(
- expand(b"%p1%d%p2%d%i%p1%d%p2%d", &[], &mut vars),
- Ok("0011".bytes().collect::<Vec<_>>())
- );
-}
-
-#[test]
-fn test_param_stack_failure_conditions() {
- let mut varstruct = Variables::new();
- let vars = &mut varstruct;
- fn get_res(
- fmt: &str,
- cap: &str,
- params: &[Param],
- vars: &mut Variables,
- ) -> Result<Vec<u8>, String> {
- let mut u8v: Vec<_> = fmt.bytes().collect();
- u8v.extend(cap.as_bytes().iter().map(|&b| b));
- expand(&u8v, params, vars)
- }
-
- let caps = ["%d", "%c", "%s", "%Pa", "%l", "%!", "%~"];
- for &cap in caps.iter() {
- let res = get_res("", cap, &[], vars);
- assert!(res.is_err(), "Op {} succeeded incorrectly with 0 stack entries", cap);
- let p = if cap == "%s" || cap == "%l" { Words("foo".to_string()) } else { Number(97) };
- let res = get_res("%p1", cap, &[p], vars);
- assert!(res.is_ok(), "Op {} failed with 1 stack entry: {}", cap, res.unwrap_err());
- }
- let caps = ["%+", "%-", "%*", "%/", "%m", "%&", "%|", "%A", "%O"];
- for &cap in caps.iter() {
- let res = expand(cap.as_bytes(), &[], vars);
- assert!(res.is_err(), "Binop {} succeeded incorrectly with 0 stack entries", cap);
- let res = get_res("%{1}", cap, &[], vars);
- assert!(res.is_err(), "Binop {} succeeded incorrectly with 1 stack entry", cap);
- let res = get_res("%{1}%{2}", cap, &[], vars);
- assert!(res.is_ok(), "Binop {} failed with 2 stack entries: {}", cap, res.unwrap_err());
- }
-}
-
-#[test]
-fn test_push_bad_param() {
- assert!(expand(b"%pa", &[], &mut Variables::new()).is_err());
-}
-
-#[test]
-fn test_comparison_ops() {
- let v = [('<', [1u8, 0u8, 0u8]), ('=', [0u8, 1u8, 0u8]), ('>', [0u8, 0u8, 1u8])];
- for &(op, bs) in v.iter() {
- let s = format!("%{{1}}%{{2}}%{}%d", op);
- let res = expand(s.as_bytes(), &[], &mut Variables::new());
- assert!(res.is_ok(), "{}", res.unwrap_err());
- assert_eq!(res.unwrap(), vec![b'0' + bs[0]]);
- let s = format!("%{{1}}%{{1}}%{}%d", op);
- let res = expand(s.as_bytes(), &[], &mut Variables::new());
- assert!(res.is_ok(), "{}", res.unwrap_err());
- assert_eq!(res.unwrap(), vec![b'0' + bs[1]]);
- let s = format!("%{{2}}%{{1}}%{}%d", op);
- let res = expand(s.as_bytes(), &[], &mut Variables::new());
- assert!(res.is_ok(), "{}", res.unwrap_err());
- assert_eq!(res.unwrap(), vec![b'0' + bs[2]]);
- }
-}
-
-#[test]
-fn test_conditionals() {
- let mut vars = Variables::new();
- let s = b"\\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m";
- let res = expand(s, &[Number(1)], &mut vars);
- assert!(res.is_ok(), "{}", res.unwrap_err());
- assert_eq!(res.unwrap(), "\\E[31m".bytes().collect::<Vec<_>>());
- let res = expand(s, &[Number(8)], &mut vars);
- assert!(res.is_ok(), "{}", res.unwrap_err());
- assert_eq!(res.unwrap(), "\\E[90m".bytes().collect::<Vec<_>>());
- let res = expand(s, &[Number(42)], &mut vars);
- assert!(res.is_ok(), "{}", res.unwrap_err());
- assert_eq!(res.unwrap(), "\\E[38;5;42m".bytes().collect::<Vec<_>>());
-}
-
-#[test]
-fn test_format() {
- let mut varstruct = Variables::new();
- let vars = &mut varstruct;
- assert_eq!(
- expand(
- b"%p1%s%p2%2s%p3%2s%p4%.2s",
- &[
- Words("foo".to_string()),
- Words("foo".to_string()),
- Words("f".to_string()),
- Words("foo".to_string())
- ],
- vars
- ),
- Ok("foofoo ffo".bytes().collect::<Vec<_>>())
- );
- assert_eq!(
- expand(b"%p1%:-4.2s", &[Words("foo".to_string())], vars),
- Ok("fo ".bytes().collect::<Vec<_>>())
- );
-
- assert_eq!(
- expand(b"%p1%d%p1%.3d%p1%5d%p1%:+d", &[Number(1)], vars),
- Ok("1001 1+1".bytes().collect::<Vec<_>>())
- );
- assert_eq!(
- expand(b"%p1%o%p1%#o%p2%6.4x%p2%#6.4X", &[Number(15), Number(27)], vars),
- Ok("17017 001b0X001B".bytes().collect::<Vec<_>>())
- );
-}
+++ /dev/null
-#![allow(non_upper_case_globals, missing_docs)]
-
-//! ncurses-compatible compiled terminfo format parsing (term(5))
-
-use super::super::TermInfo;
-use std::collections::HashMap;
-use std::io;
-use std::io::prelude::*;
-
-#[cfg(test)]
-mod tests;
-
-// These are the orders ncurses uses in its compiled format (as of 5.9). Not sure if portable.
-
-#[rustfmt::skip]
-pub static boolfnames: &[&str] = &["auto_left_margin", "auto_right_margin",
- "no_esc_ctlc", "ceol_standout_glitch", "eat_newline_glitch", "erase_overstrike", "generic_type",
- "hard_copy", "has_meta_key", "has_status_line", "insert_null_glitch", "memory_above",
- "memory_below", "move_insert_mode", "move_standout_mode", "over_strike", "status_line_esc_ok",
- "dest_tabs_magic_smso", "tilde_glitch", "transparent_underline", "xon_xoff", "needs_xon_xoff",
- "prtr_silent", "hard_cursor", "non_rev_rmcup", "no_pad_char", "non_dest_scroll_region",
- "can_change", "back_color_erase", "hue_lightness_saturation", "col_addr_glitch",
- "cr_cancels_micro_mode", "has_print_wheel", "row_addr_glitch", "semi_auto_right_margin",
- "cpi_changes_res", "lpi_changes_res", "backspaces_with_bs", "crt_no_scrolling",
- "no_correctly_working_cr", "gnu_has_meta_key", "linefeed_is_newline", "has_hardware_tabs",
- "return_does_clr_eol"];
-
-#[rustfmt::skip]
-pub static boolnames: &[&str] = &["bw", "am", "xsb", "xhp", "xenl", "eo",
- "gn", "hc", "km", "hs", "in", "db", "da", "mir", "msgr", "os", "eslok", "xt", "hz", "ul", "xon",
- "nxon", "mc5i", "chts", "nrrmc", "npc", "ndscr", "ccc", "bce", "hls", "xhpa", "crxm", "daisy",
- "xvpa", "sam", "cpix", "lpix", "OTbs", "OTns", "OTnc", "OTMT", "OTNL", "OTpt", "OTxr"];
-
-#[rustfmt::skip]
-pub static numfnames: &[&str] = &[ "columns", "init_tabs", "lines",
- "lines_of_memory", "magic_cookie_glitch", "padding_baud_rate", "virtual_terminal",
- "width_status_line", "num_labels", "label_height", "label_width", "max_attributes",
- "maximum_windows", "max_colors", "max_pairs", "no_color_video", "buffer_capacity",
- "dot_vert_spacing", "dot_horz_spacing", "max_micro_address", "max_micro_jump", "micro_col_size",
- "micro_line_size", "number_of_pins", "output_res_char", "output_res_line",
- "output_res_horz_inch", "output_res_vert_inch", "print_rate", "wide_char_size", "buttons",
- "bit_image_entwining", "bit_image_type", "magic_cookie_glitch_ul", "carriage_return_delay",
- "new_line_delay", "backspace_delay", "horizontal_tab_delay", "number_of_function_keys"];
-
-#[rustfmt::skip]
-pub static numnames: &[&str] = &[ "cols", "it", "lines", "lm", "xmc", "pb",
- "vt", "wsl", "nlab", "lh", "lw", "ma", "wnum", "colors", "pairs", "ncv", "bufsz", "spinv",
- "spinh", "maddr", "mjump", "mcs", "mls", "npins", "orc", "orl", "orhi", "orvi", "cps", "widcs",
- "btns", "bitwin", "bitype", "UTug", "OTdC", "OTdN", "OTdB", "OTdT", "OTkn"];
-
-#[rustfmt::skip]
-pub static stringfnames: &[&str] = &[ "back_tab", "bell", "carriage_return",
- "change_scroll_region", "clear_all_tabs", "clear_screen", "clr_eol", "clr_eos",
- "column_address", "command_character", "cursor_address", "cursor_down", "cursor_home",
- "cursor_invisible", "cursor_left", "cursor_mem_address", "cursor_normal", "cursor_right",
- "cursor_to_ll", "cursor_up", "cursor_visible", "delete_character", "delete_line",
- "dis_status_line", "down_half_line", "enter_alt_charset_mode", "enter_blink_mode",
- "enter_bold_mode", "enter_ca_mode", "enter_delete_mode", "enter_dim_mode", "enter_insert_mode",
- "enter_secure_mode", "enter_protected_mode", "enter_reverse_mode", "enter_standout_mode",
- "enter_underline_mode", "erase_chars", "exit_alt_charset_mode", "exit_attribute_mode",
- "exit_ca_mode", "exit_delete_mode", "exit_insert_mode", "exit_standout_mode",
- "exit_underline_mode", "flash_screen", "form_feed", "from_status_line", "init_1string",
- "init_2string", "init_3string", "init_file", "insert_character", "insert_line",
- "insert_padding", "key_backspace", "key_catab", "key_clear", "key_ctab", "key_dc", "key_dl",
- "key_down", "key_eic", "key_eol", "key_eos", "key_f0", "key_f1", "key_f10", "key_f2", "key_f3",
- "key_f4", "key_f5", "key_f6", "key_f7", "key_f8", "key_f9", "key_home", "key_ic", "key_il",
- "key_left", "key_ll", "key_npage", "key_ppage", "key_right", "key_sf", "key_sr", "key_stab",
- "key_up", "keypad_local", "keypad_xmit", "lab_f0", "lab_f1", "lab_f10", "lab_f2", "lab_f3",
- "lab_f4", "lab_f5", "lab_f6", "lab_f7", "lab_f8", "lab_f9", "meta_off", "meta_on", "newline",
- "pad_char", "parm_dch", "parm_delete_line", "parm_down_cursor", "parm_ich", "parm_index",
- "parm_insert_line", "parm_left_cursor", "parm_right_cursor", "parm_rindex", "parm_up_cursor",
- "pkey_key", "pkey_local", "pkey_xmit", "print_screen", "prtr_off", "prtr_on", "repeat_char",
- "reset_1string", "reset_2string", "reset_3string", "reset_file", "restore_cursor",
- "row_address", "save_cursor", "scroll_forward", "scroll_reverse", "set_attributes", "set_tab",
- "set_window", "tab", "to_status_line", "underline_char", "up_half_line", "init_prog", "key_a1",
- "key_a3", "key_b2", "key_c1", "key_c3", "prtr_non", "char_padding", "acs_chars", "plab_norm",
- "key_btab", "enter_xon_mode", "exit_xon_mode", "enter_am_mode", "exit_am_mode", "xon_character",
- "xoff_character", "ena_acs", "label_on", "label_off", "key_beg", "key_cancel", "key_close",
- "key_command", "key_copy", "key_create", "key_end", "key_enter", "key_exit", "key_find",
- "key_help", "key_mark", "key_message", "key_move", "key_next", "key_open", "key_options",
- "key_previous", "key_print", "key_redo", "key_reference", "key_refresh", "key_replace",
- "key_restart", "key_resume", "key_save", "key_suspend", "key_undo", "key_sbeg", "key_scancel",
- "key_scommand", "key_scopy", "key_screate", "key_sdc", "key_sdl", "key_select", "key_send",
- "key_seol", "key_sexit", "key_sfind", "key_shelp", "key_shome", "key_sic", "key_sleft",
- "key_smessage", "key_smove", "key_snext", "key_soptions", "key_sprevious", "key_sprint",
- "key_sredo", "key_sreplace", "key_sright", "key_srsume", "key_ssave", "key_ssuspend",
- "key_sundo", "req_for_input", "key_f11", "key_f12", "key_f13", "key_f14", "key_f15", "key_f16",
- "key_f17", "key_f18", "key_f19", "key_f20", "key_f21", "key_f22", "key_f23", "key_f24",
- "key_f25", "key_f26", "key_f27", "key_f28", "key_f29", "key_f30", "key_f31", "key_f32",
- "key_f33", "key_f34", "key_f35", "key_f36", "key_f37", "key_f38", "key_f39", "key_f40",
- "key_f41", "key_f42", "key_f43", "key_f44", "key_f45", "key_f46", "key_f47", "key_f48",
- "key_f49", "key_f50", "key_f51", "key_f52", "key_f53", "key_f54", "key_f55", "key_f56",
- "key_f57", "key_f58", "key_f59", "key_f60", "key_f61", "key_f62", "key_f63", "clr_bol",
- "clear_margins", "set_left_margin", "set_right_margin", "label_format", "set_clock",
- "display_clock", "remove_clock", "create_window", "goto_window", "hangup", "dial_phone",
- "quick_dial", "tone", "pulse", "flash_hook", "fixed_pause", "wait_tone", "user0", "user1",
- "user2", "user3", "user4", "user5", "user6", "user7", "user8", "user9", "orig_pair",
- "orig_colors", "initialize_color", "initialize_pair", "set_color_pair", "set_foreground",
- "set_background", "change_char_pitch", "change_line_pitch", "change_res_horz",
- "change_res_vert", "define_char", "enter_doublewide_mode", "enter_draft_quality",
- "enter_italics_mode", "enter_leftward_mode", "enter_micro_mode", "enter_near_letter_quality",
- "enter_normal_quality", "enter_shadow_mode", "enter_subscript_mode", "enter_superscript_mode",
- "enter_upward_mode", "exit_doublewide_mode", "exit_italics_mode", "exit_leftward_mode",
- "exit_micro_mode", "exit_shadow_mode", "exit_subscript_mode", "exit_superscript_mode",
- "exit_upward_mode", "micro_column_address", "micro_down", "micro_left", "micro_right",
- "micro_row_address", "micro_up", "order_of_pins", "parm_down_micro", "parm_left_micro",
- "parm_right_micro", "parm_up_micro", "select_char_set", "set_bottom_margin",
- "set_bottom_margin_parm", "set_left_margin_parm", "set_right_margin_parm", "set_top_margin",
- "set_top_margin_parm", "start_bit_image", "start_char_set_def", "stop_bit_image",
- "stop_char_set_def", "subscript_characters", "superscript_characters", "these_cause_cr",
- "zero_motion", "char_set_names", "key_mouse", "mouse_info", "req_mouse_pos", "get_mouse",
- "set_a_foreground", "set_a_background", "pkey_plab", "device_type", "code_set_init",
- "set0_des_seq", "set1_des_seq", "set2_des_seq", "set3_des_seq", "set_lr_margin",
- "set_tb_margin", "bit_image_repeat", "bit_image_newline", "bit_image_carriage_return",
- "color_names", "define_bit_image_region", "end_bit_image_region", "set_color_band",
- "set_page_length", "display_pc_char", "enter_pc_charset_mode", "exit_pc_charset_mode",
- "enter_scancode_mode", "exit_scancode_mode", "pc_term_options", "scancode_escape",
- "alt_scancode_esc", "enter_horizontal_hl_mode", "enter_left_hl_mode", "enter_low_hl_mode",
- "enter_right_hl_mode", "enter_top_hl_mode", "enter_vertical_hl_mode", "set_a_attributes",
- "set_pglen_inch", "termcap_init2", "termcap_reset", "linefeed_if_not_lf", "backspace_if_not_bs",
- "other_non_function_keys", "arrow_key_map", "acs_ulcorner", "acs_llcorner", "acs_urcorner",
- "acs_lrcorner", "acs_ltee", "acs_rtee", "acs_btee", "acs_ttee", "acs_hline", "acs_vline",
- "acs_plus", "memory_lock", "memory_unlock", "box_chars_1"];
-
-#[rustfmt::skip]
-pub static stringnames: &[&str] = &[ "cbt", "_", "cr", "csr", "tbc", "clear",
- "_", "_", "hpa", "cmdch", "cup", "cud1", "home", "civis", "cub1", "mrcup", "cnorm", "cuf1",
- "ll", "cuu1", "cvvis", "dch1", "dl1", "dsl", "hd", "smacs", "blink", "bold", "smcup", "smdc",
- "dim", "smir", "invis", "prot", "rev", "smso", "smul", "ech", "rmacs", "sgr0", "rmcup", "rmdc",
- "rmir", "rmso", "rmul", "flash", "ff", "fsl", "is1", "is2", "is3", "if", "ich1", "il1", "ip",
- "kbs", "ktbc", "kclr", "kctab", "_", "_", "kcud1", "_", "_", "_", "_", "_", "_", "_", "_", "_",
- "_", "_", "_", "_", "_", "khome", "_", "_", "kcub1", "_", "knp", "kpp", "kcuf1", "_", "_",
- "khts", "_", "rmkx", "smkx", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "rmm", "_",
- "_", "pad", "dch", "dl", "cud", "ich", "indn", "il", "cub", "cuf", "rin", "cuu", "pfkey",
- "pfloc", "pfx", "mc0", "mc4", "_", "rep", "rs1", "rs2", "rs3", "rf", "rc", "vpa", "sc", "ind",
- "ri", "sgr", "_", "wind", "_", "tsl", "uc", "hu", "iprog", "_", "_", "_", "_", "_", "mc5p",
- "rmp", "acsc", "pln", "kcbt", "smxon", "rmxon", "smam", "rmam", "xonc", "xoffc", "_", "smln",
- "rmln", "_", "kcan", "kclo", "kcmd", "kcpy", "kcrt", "_", "kent", "kext", "kfnd", "khlp",
- "kmrk", "kmsg", "kmov", "knxt", "kopn", "kopt", "kprv", "kprt", "krdo", "kref", "krfr", "krpl",
- "krst", "kres", "ksav", "kspd", "kund", "kBEG", "kCAN", "kCMD", "kCPY", "kCRT", "_", "_",
- "kslt", "kEND", "kEOL", "kEXT", "kFND", "kHLP", "kHOM", "_", "kLFT", "kMSG", "kMOV", "kNXT",
- "kOPT", "kPRV", "kPRT", "kRDO", "kRPL", "kRIT", "kRES", "kSAV", "kSPD", "kUND", "rfi", "_", "_",
- "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_",
- "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_",
- "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_",
- "dclk", "rmclk", "cwin", "wingo", "_", "dial", "qdial", "_", "_", "hook", "pause", "wait", "_",
- "_", "_", "_", "_", "_", "_", "_", "_", "_", "op", "oc", "initc", "initp", "scp", "setf",
- "setb", "cpi", "lpi", "chr", "cvr", "defc", "swidm", "sdrfq", "sitm", "slm", "smicm", "snlq",
- "snrmq", "sshm", "ssubm", "ssupm", "sum", "rwidm", "ritm", "rlm", "rmicm", "rshm", "rsubm",
- "rsupm", "rum", "mhpa", "mcud1", "mcub1", "mcuf1", "mvpa", "mcuu1", "porder", "mcud", "mcub",
- "mcuf", "mcuu", "scs", "smgb", "smgbp", "smglp", "smgrp", "smgt", "smgtp", "sbim", "scsd",
- "rbim", "rcsd", "subcs", "supcs", "docr", "zerom", "csnm", "kmous", "minfo", "reqmp", "getm",
- "setaf", "setab", "pfxl", "devt", "csin", "s0ds", "s1ds", "s2ds", "s3ds", "smglr", "smgtb",
- "birep", "binel", "bicr", "colornm", "defbi", "endbi", "setcolor", "slines", "dispc", "smpch",
- "rmpch", "smsc", "rmsc", "pctrm", "scesc", "scesa", "ehhlm", "elhlm", "elohlm", "erhlm",
- "ethlm", "evhlm", "sgr1", "slength", "OTi2", "OTrs", "OTnl", "OTbs", "OTko", "OTma", "OTG2",
- "OTG3", "OTG1", "OTG4", "OTGR", "OTGL", "OTGU", "OTGD", "OTGH", "OTGV", "OTGC", "meml", "memu",
- "box1"];
-
-fn read_le_u16(r: &mut dyn io::Read) -> io::Result<u16> {
- let mut b = [0; 2];
- r.read_exact(&mut b)?;
- Ok((b[0] as u16) | ((b[1] as u16) << 8))
-}
-
-fn read_le_u32(r: &mut dyn io::Read) -> io::Result<u32> {
- let mut b = [0; 4];
- r.read_exact(&mut b)?;
- Ok((b[0] as u32) | ((b[1] as u32) << 8) | ((b[2] as u32) << 16) | ((b[3] as u32) << 24))
-}
-
-fn read_byte(r: &mut dyn io::Read) -> io::Result<u8> {
- match r.bytes().next() {
- Some(s) => s,
- None => Err(io::Error::new(io::ErrorKind::Other, "end of file")),
- }
-}
-
-/// Parse a compiled terminfo entry, using long capability names if `longnames`
-/// is true
-pub fn parse(file: &mut dyn io::Read, longnames: bool) -> Result<TermInfo, String> {
- macro_rules! t( ($e:expr) => (
- match $e {
- Ok(e) => e,
- Err(e) => return Err(e.to_string())
- }
- ) );
-
- let (bnames, snames, nnames) = if longnames {
- (boolfnames, stringfnames, numfnames)
- } else {
- (boolnames, stringnames, numnames)
- };
-
- // Check magic number
- let magic = t!(read_le_u16(file));
-
- let extended = match magic {
- 0o0432 => false,
- 0o01036 => true,
- _ => return Err(format!("invalid magic number, found {:o}", magic)),
- };
-
- // According to the spec, these fields must be >= -1 where -1 means that the feature is not
- // supported. Using 0 instead of -1 works because we skip sections with length 0.
- macro_rules! read_nonneg {
- () => {{
- match t!(read_le_u16(file)) as i16 {
- n if n >= 0 => n as usize,
- -1 => 0,
- _ => return Err("incompatible file: length fields must be >= -1".to_string()),
- }
- }};
- }
-
- let names_bytes = read_nonneg!();
- let bools_bytes = read_nonneg!();
- let numbers_count = read_nonneg!();
- let string_offsets_count = read_nonneg!();
- let string_table_bytes = read_nonneg!();
-
- if names_bytes == 0 {
- return Err("incompatible file: names field must be at least 1 byte wide".to_string());
- }
-
- if bools_bytes > boolnames.len() {
- return Err("incompatible file: more booleans than expected".to_string());
- }
-
- if numbers_count > numnames.len() {
- return Err("incompatible file: more numbers than expected".to_string());
- }
-
- if string_offsets_count > stringnames.len() {
- return Err("incompatible file: more string offsets than expected".to_string());
- }
-
- // don't read NUL
- let mut bytes = Vec::new();
- t!(file.take((names_bytes - 1) as u64).read_to_end(&mut bytes));
- let names_str = match String::from_utf8(bytes) {
- Ok(s) => s,
- Err(_) => return Err("input not utf-8".to_string()),
- };
-
- let term_names: Vec<String> = names_str.split('|').map(|s| s.to_string()).collect();
- // consume NUL
- if t!(read_byte(file)) != b'\0' {
- return Err("incompatible file: missing null terminator for names section".to_string());
- }
-
- let bools_map: HashMap<String, bool> = t! {
- (0..bools_bytes).filter_map(|i| match read_byte(file) {
- Err(e) => Some(Err(e)),
- Ok(1) => Some(Ok((bnames[i].to_string(), true))),
- Ok(_) => None
- }).collect()
- };
-
- if (bools_bytes + names_bytes) % 2 == 1 {
- t!(read_byte(file)); // compensate for padding
- }
-
- let numbers_map: HashMap<String, u32> = t! {
- (0..numbers_count).filter_map(|i| {
- let number = if extended { read_le_u32(file) } else { read_le_u16(file).map(Into::into) };
-
- match number {
- Ok(0xFFFF) => None,
- Ok(n) => Some(Ok((nnames[i].to_string(), n))),
- Err(e) => Some(Err(e))
- }
- }).collect()
- };
-
- let string_map: HashMap<String, Vec<u8>> = if string_offsets_count > 0 {
- let string_offsets: Vec<u16> =
- t!((0..string_offsets_count).map(|_| read_le_u16(file)).collect());
-
- let mut string_table = Vec::new();
- t!(file.take(string_table_bytes as u64).read_to_end(&mut string_table));
-
- t!(string_offsets
- .into_iter()
- .enumerate()
- .filter(|&(_, offset)| {
- // non-entry
- offset != 0xFFFF
- })
- .map(|(i, offset)| {
- let offset = offset as usize;
-
- let name = if snames[i] == "_" { stringfnames[i] } else { snames[i] };
-
- if offset == 0xFFFE {
- // undocumented: FFFE indicates cap@, which means the capability is not present
- // unsure if the handling for this is correct
- return Ok((name.to_string(), Vec::new()));
- }
-
- // Find the offset of the NUL we want to go to
- let nulpos = string_table[offset..string_table_bytes].iter().position(|&b| b == 0);
- match nulpos {
- Some(len) => {
- Ok((name.to_string(), string_table[offset..offset + len].to_vec()))
- }
- None => Err("invalid file: missing NUL in string_table".to_string()),
- }
- })
- .collect())
- } else {
- HashMap::new()
- };
-
- // And that's all there is to it
- Ok(TermInfo { names: term_names, bools: bools_map, numbers: numbers_map, strings: string_map })
-}
-
-/// Creates a dummy TermInfo struct for msys terminals
-pub fn msys_terminfo() -> TermInfo {
- let mut strings = HashMap::new();
- strings.insert("sgr0".to_string(), b"\x1B[0m".to_vec());
- strings.insert("bold".to_string(), b"\x1B[1m".to_vec());
- strings.insert("setaf".to_string(), b"\x1B[3%p1%dm".to_vec());
- strings.insert("setab".to_string(), b"\x1B[4%p1%dm".to_vec());
-
- let mut numbers = HashMap::new();
- numbers.insert("colors".to_string(), 8);
-
- TermInfo {
- names: vec!["cygwin".to_string()], // msys is a fork of an older cygwin version
- bools: HashMap::new(),
- numbers,
- strings,
- }
-}
+++ /dev/null
-use super::*;
-
-#[test]
-fn test_veclens() {
- assert_eq!(boolfnames.len(), boolnames.len());
- assert_eq!(numfnames.len(), numnames.len());
- assert_eq!(stringfnames.len(), stringnames.len());
-}
+++ /dev/null
-//! ncurses-compatible database discovery.
-//!
-//! Does not support hashed database, only filesystem!
-
-use std::env;
-use std::fs;
-use std::path::PathBuf;
-
-#[cfg(test)]
-mod tests;
-
-/// Return path to database entry for `term`
-#[allow(deprecated)]
-pub fn get_dbpath_for_term(term: &str) -> Option<PathBuf> {
- let mut dirs_to_search = Vec::new();
- let first_char = term.chars().next()?;
-
- // Find search directory
- if let Some(dir) = env::var_os("TERMINFO") {
- dirs_to_search.push(PathBuf::from(dir));
- }
-
- if let Ok(dirs) = env::var("TERMINFO_DIRS") {
- for i in dirs.split(':') {
- if i == "" {
- dirs_to_search.push(PathBuf::from("/usr/share/terminfo"));
- } else {
- dirs_to_search.push(PathBuf::from(i));
- }
- }
- } else {
- // Found nothing in TERMINFO_DIRS, use the default paths:
- // According to /etc/terminfo/README, after looking at
- // ~/.terminfo, ncurses will search /etc/terminfo, then
- // /lib/terminfo, and eventually /usr/share/terminfo.
- // On Haiku the database can be found at /boot/system/data/terminfo
- if let Some(mut homedir) = env::home_dir() {
- homedir.push(".terminfo");
- dirs_to_search.push(homedir)
- }
-
- dirs_to_search.push(PathBuf::from("/etc/terminfo"));
- dirs_to_search.push(PathBuf::from("/lib/terminfo"));
- dirs_to_search.push(PathBuf::from("/usr/share/terminfo"));
- dirs_to_search.push(PathBuf::from("/boot/system/data/terminfo"));
- }
-
- // Look for the terminal in all of the search directories
- for mut p in dirs_to_search {
- if fs::metadata(&p).is_ok() {
- p.push(&first_char.to_string());
- p.push(&term);
- if fs::metadata(&p).is_ok() {
- return Some(p);
- }
- p.pop();
- p.pop();
-
- // on some installations the dir is named after the hex of the char
- // (e.g., macOS)
- p.push(&format!("{:x}", first_char as usize));
- p.push(term);
- if fs::metadata(&p).is_ok() {
- return Some(p);
- }
- }
- }
- None
-}
+++ /dev/null
-use super::*;
-
-#[test]
-#[ignore = "buildbots don't have ncurses installed and I can't mock everything I need"]
-fn test_get_dbpath_for_term() {
- // woefully inadequate test coverage
- // note: current tests won't work with non-standard terminfo hierarchies (e.g., macOS's)
- use std::env;
- // FIXME (#9639): This needs to handle non-utf8 paths
- fn x(t: &str) -> String {
- let p = get_dbpath_for_term(t).expect("no terminfo entry found");
- p.to_str().unwrap().to_string()
- }
- assert!(x("screen") == "/usr/share/terminfo/s/screen");
- assert!(get_dbpath_for_term("") == None);
- env::set_var("TERMINFO_DIRS", ":");
- assert!(x("screen") == "/usr/share/terminfo/s/screen");
- env::remove_var("TERMINFO_DIRS");
-}
+++ /dev/null
-//! Windows console handling
-
-// FIXME (#13400): this is only a tiny fraction of the Windows console api
-
-use std::io;
-use std::io::prelude::*;
-
-use crate::color;
-use crate::Attr;
-use crate::Terminal;
-
-/// A Terminal implementation that uses the Win32 Console API.
-pub struct WinConsole<T> {
- buf: T,
- def_foreground: color::Color,
- def_background: color::Color,
- foreground: color::Color,
- background: color::Color,
-}
-
-type SHORT = i16;
-type WORD = u16;
-type DWORD = u32;
-type BOOL = i32;
-type HANDLE = *mut u8;
-
-#[allow(non_snake_case)]
-#[repr(C)]
-struct SMALL_RECT {
- Left: SHORT,
- Top: SHORT,
- Right: SHORT,
- Bottom: SHORT,
-}
-
-#[allow(non_snake_case)]
-#[repr(C)]
-struct COORD {
- X: SHORT,
- Y: SHORT,
-}
-
-#[allow(non_snake_case)]
-#[repr(C)]
-struct CONSOLE_SCREEN_BUFFER_INFO {
- dwSize: COORD,
- dwCursorPosition: COORD,
- wAttributes: WORD,
- srWindow: SMALL_RECT,
- dwMaximumWindowSize: COORD,
-}
-
-#[allow(non_snake_case)]
-#[link(name = "kernel32")]
-extern "system" {
- fn SetConsoleTextAttribute(handle: HANDLE, attr: WORD) -> BOOL;
- fn GetStdHandle(which: DWORD) -> HANDLE;
- fn GetConsoleScreenBufferInfo(handle: HANDLE, info: *mut CONSOLE_SCREEN_BUFFER_INFO) -> BOOL;
-}
-
-fn color_to_bits(color: color::Color) -> u16 {
- // magic numbers from mingw-w64's wincon.h
-
- let bits = match color % 8 {
- color::BLACK => 0,
- color::BLUE => 0x1,
- color::GREEN => 0x2,
- color::RED => 0x4,
- color::YELLOW => 0x2 | 0x4,
- color::MAGENTA => 0x1 | 0x4,
- color::CYAN => 0x1 | 0x2,
- color::WHITE => 0x1 | 0x2 | 0x4,
- _ => unreachable!(),
- };
-
- if color >= 8 { bits | 0x8 } else { bits }
-}
-
-fn bits_to_color(bits: u16) -> color::Color {
- let color = match bits & 0x7 {
- 0 => color::BLACK,
- 0x1 => color::BLUE,
- 0x2 => color::GREEN,
- 0x4 => color::RED,
- 0x6 => color::YELLOW,
- 0x5 => color::MAGENTA,
- 0x3 => color::CYAN,
- 0x7 => color::WHITE,
- _ => unreachable!(),
- };
-
- color | (u32::from(bits) & 0x8) // copy the hi-intensity bit
-}
-
-impl<T: Write + Send + 'static> WinConsole<T> {
- fn apply(&mut self) {
- let _unused = self.buf.flush();
- let mut accum: WORD = 0;
- accum |= color_to_bits(self.foreground);
- accum |= color_to_bits(self.background) << 4;
-
- unsafe {
- // Magic -11 means stdout, from
- // https://docs.microsoft.com/en-us/windows/console/getstdhandle
- //
- // You may be wondering, "but what about stderr?", and the answer
- // to that is that setting terminal attributes on the stdout
- // handle also sets them for stderr, since they go to the same
- // terminal! Admittedly, this is fragile, since stderr could be
- // redirected to a different console. This is good enough for
- // rustc though. See #13400.
- let out = GetStdHandle(-11i32 as DWORD);
- SetConsoleTextAttribute(out, accum);
- }
- }
-
- /// Returns `None` whenever the terminal cannot be created for some reason.
- pub fn new(out: T) -> io::Result<WinConsole<T>> {
- use std::mem::MaybeUninit;
-
- let fg;
- let bg;
- unsafe {
- let mut buffer_info = MaybeUninit::<CONSOLE_SCREEN_BUFFER_INFO>::uninit();
- if GetConsoleScreenBufferInfo(GetStdHandle(-11i32 as DWORD), buffer_info.as_mut_ptr())
- != 0
- {
- let buffer_info = buffer_info.assume_init();
- fg = bits_to_color(buffer_info.wAttributes);
- bg = bits_to_color(buffer_info.wAttributes >> 4);
- } else {
- fg = color::WHITE;
- bg = color::BLACK;
- }
- }
- Ok(WinConsole {
- buf: out,
- def_foreground: fg,
- def_background: bg,
- foreground: fg,
- background: bg,
- })
- }
-}
-
-impl<T: Write> Write for WinConsole<T> {
- fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
- self.buf.write(buf)
- }
-
- fn flush(&mut self) -> io::Result<()> {
- self.buf.flush()
- }
-}
-
-impl<T: Write + Send + 'static> Terminal for WinConsole<T> {
- type Output = T;
-
- fn fg(&mut self, color: color::Color) -> io::Result<bool> {
- self.foreground = color;
- self.apply();
-
- Ok(true)
- }
-
- fn bg(&mut self, color: color::Color) -> io::Result<bool> {
- self.background = color;
- self.apply();
-
- Ok(true)
- }
-
- fn attr(&mut self, attr: Attr) -> io::Result<bool> {
- match attr {
- Attr::ForegroundColor(f) => {
- self.foreground = f;
- self.apply();
- Ok(true)
- }
- Attr::BackgroundColor(b) => {
- self.background = b;
- self.apply();
- Ok(true)
- }
- _ => Ok(false),
- }
- }
-
- fn supports_attr(&self, attr: Attr) -> bool {
- // it claims support for underscore and reverse video, but I can't get
- // it to do anything -cmr
- match attr {
- Attr::ForegroundColor(_) | Attr::BackgroundColor(_) => true,
- _ => false,
- }
- }
-
- fn reset(&mut self) -> io::Result<bool> {
- self.foreground = self.def_foreground;
- self.background = self.def_background;
- self.apply();
-
- Ok(true)
- }
-
- fn get_ref(&self) -> &T {
- &self.buf
- }
-
- fn get_mut(&mut self) -> &mut T {
- &mut self.buf
- }
-
- fn into_inner(self) -> T
- where
- Self: Sized,
- {
- self.buf
- }
-}
[dependencies]
cfg-if = { version = "0.1.8", features = ['rustc-dep-of-std'] }
getopts = { version = "0.2.21", features = ['rustc-dep-of-std'] }
-term = { path = "../term" }
std = { path = "../std" }
core = { path = "../core" }
libc = { version = "0.2", default-features = false }
formatters::{JsonFormatter, JunitFormatter, OutputFormatter, PrettyFormatter, TerseFormatter},
helpers::{concurrency::get_concurrency, metrics::MetricMap},
options::{Options, OutputFormat},
- run_tests,
+ run_tests, term,
test_result::TestResult,
time::{TestExecTime, TestSuiteExecTime},
types::{NamePadding, TestDesc, TestDescAndFn},
use crate::{
bench::fmt_bench_samples,
console::{ConsoleTestState, OutputLocation},
+ term,
test_result::TestResult,
time,
types::TestDesc,
use crate::{
bench::fmt_bench_samples,
console::{ConsoleTestState, OutputLocation},
+ term,
test_result::TestResult,
time,
types::NamePadding,
#![crate_name = "test"]
#![unstable(feature = "test", issue = "50297")]
#![doc(test(attr(deny(warnings))))]
-#![cfg_attr(unix, feature(libc))]
+#![feature(libc)]
#![feature(rustc_private)]
#![feature(nll)]
#![feature(available_concurrency)]
mod helpers;
mod options;
pub mod stats;
+mod term;
mod test_result;
mod time;
mod types;
--- /dev/null
+//! Terminal formatting module.
+//!
+//! This module provides the `Terminal` trait, which abstracts over an [ANSI
+//! Terminal][ansi] to provide color printing, among other things. There are two
+//! implementations, the `TerminfoTerminal`, which uses control characters from
+//! a [terminfo][ti] database, and `WinConsole`, which uses the [Win32 Console
+//! API][win].
+//!
+//! [ansi]: https://en.wikipedia.org/wiki/ANSI_escape_code
+//! [win]: https://docs.microsoft.com/en-us/windows/console/character-mode-applications
+//! [ti]: https://en.wikipedia.org/wiki/Terminfo
+
+#![deny(missing_docs)]
+
+use std::io::{self, prelude::*};
+
+pub(crate) use terminfo::TerminfoTerminal;
+#[cfg(windows)]
+pub(crate) use win::WinConsole;
+
+pub(crate) mod terminfo;
+
+#[cfg(windows)]
+mod win;
+
+/// Alias for stdout terminals.
+pub(crate) type StdoutTerminal = dyn Terminal + Send;
+
+#[cfg(not(windows))]
+/// Returns a Terminal wrapping stdout, or None if a terminal couldn't be
+/// opened.
+pub(crate) fn stdout() -> Option<Box<StdoutTerminal>> {
+ TerminfoTerminal::new(io::stdout()).map(|t| Box::new(t) as Box<StdoutTerminal>)
+}
+
+#[cfg(windows)]
+/// Returns a Terminal wrapping stdout, or None if a terminal couldn't be
+/// opened.
+pub(crate) fn stdout() -> Option<Box<StdoutTerminal>> {
+ TerminfoTerminal::new(io::stdout())
+ .map(|t| Box::new(t) as Box<StdoutTerminal>)
+ .or_else(|| WinConsole::new(io::stdout()).ok().map(|t| Box::new(t) as Box<StdoutTerminal>))
+}
+
+/// Terminal color definitions
+#[allow(missing_docs)]
+#[cfg_attr(not(windows), allow(dead_code))]
+pub(crate) mod color {
+ /// Number for a terminal color
+ pub(crate) type Color = u32;
+
+ pub(crate) const BLACK: Color = 0;
+ pub(crate) const RED: Color = 1;
+ pub(crate) const GREEN: Color = 2;
+ pub(crate) const YELLOW: Color = 3;
+ pub(crate) const BLUE: Color = 4;
+ pub(crate) const MAGENTA: Color = 5;
+ pub(crate) const CYAN: Color = 6;
+ pub(crate) const WHITE: Color = 7;
+}
+
+/// A terminal with similar capabilities to an ANSI Terminal
+/// (foreground/background colors etc).
+pub trait Terminal: Write {
+ /// Sets the foreground color to the given color.
+ ///
+ /// If the color is a bright color, but the terminal only supports 8 colors,
+ /// the corresponding normal color will be used instead.
+ ///
+ /// Returns `Ok(true)` if the color was set, `Ok(false)` otherwise, and `Err(e)`
+ /// if there was an I/O error.
+ fn fg(&mut self, color: color::Color) -> io::Result<bool>;
+
+ /// Resets all terminal attributes and colors to their defaults.
+ ///
+ /// Returns `Ok(true)` if the terminal was reset, `Ok(false)` otherwise, and `Err(e)` if there
+ /// was an I/O error.
+ ///
+ /// *Note: This does not flush.*
+ ///
+ /// That means the reset command may get buffered so, if you aren't planning on doing anything
+ /// else that might flush stdout's buffer (e.g., writing a line of text), you should flush after
+ /// calling reset.
+ fn reset(&mut self) -> io::Result<bool>;
+}
--- /dev/null
+//! Terminfo database interface.
+
+use std::collections::HashMap;
+use std::env;
+use std::error;
+use std::fmt;
+use std::fs::File;
+use std::io::{self, prelude::*, BufReader};
+use std::path::Path;
+
+use super::color;
+use super::Terminal;
+
+use parm::{expand, Param, Variables};
+use parser::compiled::{msys_terminfo, parse};
+use searcher::get_dbpath_for_term;
+
+/// A parsed terminfo database entry.
+#[derive(Debug)]
+pub(crate) struct TermInfo {
+ /// Names for the terminal
+ pub(crate) names: Vec<String>,
+ /// Map of capability name to boolean value
+ pub(crate) bools: HashMap<String, bool>,
+ /// Map of capability name to numeric value
+ pub(crate) numbers: HashMap<String, u32>,
+ /// Map of capability name to raw (unexpanded) string
+ pub(crate) strings: HashMap<String, Vec<u8>>,
+}
+
+/// A terminfo creation error.
+#[derive(Debug)]
+pub(crate) enum Error {
+ /// TermUnset Indicates that the environment doesn't include enough information to find
+ /// the terminfo entry.
+ TermUnset,
+ /// MalformedTerminfo indicates that parsing the terminfo entry failed.
+ MalformedTerminfo(String),
+ /// io::Error forwards any io::Errors encountered when finding or reading the terminfo entry.
+ IoError(io::Error),
+}
+
+impl error::Error for Error {
+ fn source(&self) -> Option<&(dyn error::Error + 'static)> {
+ use Error::*;
+ match self {
+ IoError(e) => Some(e),
+ _ => None,
+ }
+ }
+}
+
+impl fmt::Display for Error {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ use Error::*;
+ match *self {
+ TermUnset => Ok(()),
+ MalformedTerminfo(ref e) => e.fmt(f),
+ IoError(ref e) => e.fmt(f),
+ }
+ }
+}
+
+impl TermInfo {
+ /// Creates a TermInfo based on current environment.
+ pub(crate) fn from_env() -> Result<TermInfo, Error> {
+ let term = match env::var("TERM") {
+ Ok(name) => TermInfo::from_name(&name),
+ Err(..) => return Err(Error::TermUnset),
+ };
+
+ if term.is_err() && env::var("MSYSCON").map_or(false, |s| "mintty.exe" == s) {
+ // msys terminal
+ Ok(msys_terminfo())
+ } else {
+ term
+ }
+ }
+
+ /// Creates a TermInfo for the named terminal.
+ pub(crate) fn from_name(name: &str) -> Result<TermInfo, Error> {
+ get_dbpath_for_term(name)
+ .ok_or_else(|| {
+ Error::IoError(io::Error::new(io::ErrorKind::NotFound, "terminfo file not found"))
+ })
+ .and_then(|p| TermInfo::from_path(&(*p)))
+ }
+
+ /// Parse the given TermInfo.
+ pub(crate) fn from_path<P: AsRef<Path>>(path: P) -> Result<TermInfo, Error> {
+ Self::_from_path(path.as_ref())
+ }
+ // Keep the metadata small
+ fn _from_path(path: &Path) -> Result<TermInfo, Error> {
+ let file = File::open(path).map_err(Error::IoError)?;
+ let mut reader = BufReader::new(file);
+ parse(&mut reader, false).map_err(Error::MalformedTerminfo)
+ }
+}
+
+pub(crate) mod searcher;
+
+/// TermInfo format parsing.
+pub(crate) mod parser {
+ //! ncurses-compatible compiled terminfo format parsing (term(5))
+ pub(crate) mod compiled;
+}
+pub(crate) mod parm;
+
+/// A Terminal that knows how many colors it supports, with a reference to its
+/// parsed Terminfo database record.
+pub(crate) struct TerminfoTerminal<T> {
+ num_colors: u32,
+ out: T,
+ ti: TermInfo,
+}
+
+impl<T: Write + Send> Terminal for TerminfoTerminal<T> {
+ fn fg(&mut self, color: color::Color) -> io::Result<bool> {
+ let color = self.dim_if_necessary(color);
+ if self.num_colors > color {
+ return self.apply_cap("setaf", &[Param::Number(color as i32)]);
+ }
+ Ok(false)
+ }
+
+ fn reset(&mut self) -> io::Result<bool> {
+ // are there any terminals that have color/attrs and not sgr0?
+ // Try falling back to sgr, then op
+ let cmd = match ["sgr0", "sgr", "op"].iter().find_map(|cap| self.ti.strings.get(*cap)) {
+ Some(op) => match expand(&op, &[], &mut Variables::new()) {
+ Ok(cmd) => cmd,
+ Err(e) => return Err(io::Error::new(io::ErrorKind::InvalidData, e)),
+ },
+ None => return Ok(false),
+ };
+ self.out.write_all(&cmd).and(Ok(true))
+ }
+}
+
+impl<T: Write + Send> TerminfoTerminal<T> {
+ /// Creates a new TerminfoTerminal with the given TermInfo and Write.
+ pub(crate) fn new_with_terminfo(out: T, terminfo: TermInfo) -> TerminfoTerminal<T> {
+ let nc = if terminfo.strings.contains_key("setaf") && terminfo.strings.contains_key("setab")
+ {
+ terminfo.numbers.get("colors").map_or(0, |&n| n)
+ } else {
+ 0
+ };
+
+ TerminfoTerminal { out, ti: terminfo, num_colors: nc }
+ }
+
+ /// Creates a new TerminfoTerminal for the current environment with the given Write.
+ ///
+ /// Returns `None` when the terminfo cannot be found or parsed.
+ pub(crate) fn new(out: T) -> Option<TerminfoTerminal<T>> {
+ TermInfo::from_env().map(move |ti| TerminfoTerminal::new_with_terminfo(out, ti)).ok()
+ }
+
+ fn dim_if_necessary(&self, color: color::Color) -> color::Color {
+ if color >= self.num_colors && color >= 8 && color < 16 { color - 8 } else { color }
+ }
+
+ fn apply_cap(&mut self, cmd: &str, params: &[Param]) -> io::Result<bool> {
+ match self.ti.strings.get(cmd) {
+ Some(cmd) => match expand(&cmd, params, &mut Variables::new()) {
+ Ok(s) => self.out.write_all(&s).and(Ok(true)),
+ Err(e) => Err(io::Error::new(io::ErrorKind::InvalidData, e)),
+ },
+ None => Ok(false),
+ }
+ }
+}
+
+impl<T: Write> Write for TerminfoTerminal<T> {
+ fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+ self.out.write(buf)
+ }
+
+ fn flush(&mut self) -> io::Result<()> {
+ self.out.flush()
+ }
+}
--- /dev/null
+//! Parameterized string expansion
+
+use self::Param::*;
+use self::States::*;
+
+use std::iter::repeat;
+
+#[cfg(test)]
+mod tests;
+
+#[derive(Clone, Copy, PartialEq)]
+enum States {
+ Nothing,
+ Percent,
+ SetVar,
+ GetVar,
+ PushParam,
+ CharConstant,
+ CharClose,
+ IntConstant(i32),
+ FormatPattern(Flags, FormatState),
+ SeekIfElse(usize),
+ SeekIfElsePercent(usize),
+ SeekIfEnd(usize),
+ SeekIfEndPercent(usize),
+}
+
+#[derive(Copy, PartialEq, Clone)]
+enum FormatState {
+ Flags,
+ Width,
+ Precision,
+}
+
+/// Types of parameters a capability can use
+#[allow(missing_docs)]
+#[derive(Clone)]
+pub(crate) enum Param {
+ Number(i32),
+}
+
+/// Container for static and dynamic variable arrays
+pub(crate) struct Variables {
+ /// Static variables A-Z
+ sta_va: [Param; 26],
+ /// Dynamic variables a-z
+ dyn_va: [Param; 26],
+}
+
+impl Variables {
+ /// Returns a new zero-initialized Variables
+ pub(crate) fn new() -> Variables {
+ Variables {
+ sta_va: [
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ ],
+ dyn_va: [
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ ],
+ }
+ }
+}
+
+/// Expand a parameterized capability
+///
+/// # Arguments
+/// * `cap` - string to expand
+/// * `params` - vector of params for %p1 etc
+/// * `vars` - Variables struct for %Pa etc
+///
+/// To be compatible with ncurses, `vars` should be the same between calls to `expand` for
+/// multiple capabilities for the same terminal.
+pub(crate) fn expand(
+ cap: &[u8],
+ params: &[Param],
+ vars: &mut Variables,
+) -> Result<Vec<u8>, String> {
+ let mut state = Nothing;
+
+ // expanded cap will only rarely be larger than the cap itself
+ let mut output = Vec::with_capacity(cap.len());
+
+ let mut stack: Vec<Param> = Vec::new();
+
+ // Copy parameters into a local vector for mutability
+ let mut mparams = [
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ Number(0),
+ ];
+ for (dst, src) in mparams.iter_mut().zip(params.iter()) {
+ *dst = (*src).clone();
+ }
+
+ for &c in cap.iter() {
+ let cur = c as char;
+ let mut old_state = state;
+ match state {
+ Nothing => {
+ if cur == '%' {
+ state = Percent;
+ } else {
+ output.push(c);
+ }
+ }
+ Percent => {
+ match cur {
+ '%' => {
+ output.push(c);
+ state = Nothing
+ }
+ 'c' => {
+ match stack.pop() {
+ // if c is 0, use 0200 (128) for ncurses compatibility
+ Some(Number(0)) => output.push(128u8),
+ // Don't check bounds. ncurses just casts and truncates.
+ Some(Number(c)) => output.push(c as u8),
+ None => return Err("stack is empty".to_string()),
+ }
+ }
+ 'p' => state = PushParam,
+ 'P' => state = SetVar,
+ 'g' => state = GetVar,
+ '\'' => state = CharConstant,
+ '{' => state = IntConstant(0),
+ 'l' => match stack.pop() {
+ Some(_) => return Err("a non-str was used with %l".to_string()),
+ None => return Err("stack is empty".to_string()),
+ },
+ '+' | '-' | '/' | '*' | '^' | '&' | '|' | 'm' => {
+ match (stack.pop(), stack.pop()) {
+ (Some(Number(y)), Some(Number(x))) => stack.push(Number(match cur {
+ '+' => x + y,
+ '-' => x - y,
+ '*' => x * y,
+ '/' => x / y,
+ '|' => x | y,
+ '&' => x & y,
+ '^' => x ^ y,
+ 'm' => x % y,
+ _ => unreachable!("All cases handled"),
+ })),
+ _ => return Err("stack is empty".to_string()),
+ }
+ }
+ '=' | '>' | '<' | 'A' | 'O' => match (stack.pop(), stack.pop()) {
+ (Some(Number(y)), Some(Number(x))) => stack.push(Number(
+ if match cur {
+ '=' => x == y,
+ '<' => x < y,
+ '>' => x > y,
+ 'A' => x > 0 && y > 0,
+ 'O' => x > 0 || y > 0,
+ _ => unreachable!(),
+ } {
+ 1
+ } else {
+ 0
+ },
+ )),
+ _ => return Err("stack is empty".to_string()),
+ },
+ '!' | '~' => match stack.pop() {
+ Some(Number(x)) => stack.push(Number(match cur {
+ '!' if x > 0 => 0,
+ '!' => 1,
+ '~' => !x,
+ _ => unreachable!(),
+ })),
+ None => return Err("stack is empty".to_string()),
+ },
+ 'i' => match (&mparams[0], &mparams[1]) {
+ (&Number(x), &Number(y)) => {
+ mparams[0] = Number(x + 1);
+ mparams[1] = Number(y + 1);
+ }
+ },
+
+ // printf-style support for %doxXs
+ 'd' | 'o' | 'x' | 'X' | 's' => {
+ if let Some(arg) = stack.pop() {
+ let flags = Flags::new();
+ let res = format(arg, FormatOp::from_char(cur), flags)?;
+ output.extend(res.iter().cloned());
+ } else {
+ return Err("stack is empty".to_string());
+ }
+ }
+ ':' | '#' | ' ' | '.' | '0'..='9' => {
+ let mut flags = Flags::new();
+ let mut fstate = FormatState::Flags;
+ match cur {
+ ':' => (),
+ '#' => flags.alternate = true,
+ ' ' => flags.space = true,
+ '.' => fstate = FormatState::Precision,
+ '0'..='9' => {
+ flags.width = cur as usize - '0' as usize;
+ fstate = FormatState::Width;
+ }
+ _ => unreachable!(),
+ }
+ state = FormatPattern(flags, fstate);
+ }
+
+ // conditionals
+ '?' => (),
+ 't' => match stack.pop() {
+ Some(Number(0)) => state = SeekIfElse(0),
+ Some(Number(_)) => (),
+ None => return Err("stack is empty".to_string()),
+ },
+ 'e' => state = SeekIfEnd(0),
+ ';' => (),
+ _ => return Err(format!("unrecognized format option {}", cur)),
+ }
+ }
+ PushParam => {
+ // params are 1-indexed
+ stack.push(
+ mparams[match cur.to_digit(10) {
+ Some(d) => d as usize - 1,
+ None => return Err("bad param number".to_string()),
+ }]
+ .clone(),
+ );
+ }
+ SetVar => {
+ if cur >= 'A' && cur <= 'Z' {
+ if let Some(arg) = stack.pop() {
+ let idx = (cur as u8) - b'A';
+ vars.sta_va[idx as usize] = arg;
+ } else {
+ return Err("stack is empty".to_string());
+ }
+ } else if cur >= 'a' && cur <= 'z' {
+ if let Some(arg) = stack.pop() {
+ let idx = (cur as u8) - b'a';
+ vars.dyn_va[idx as usize] = arg;
+ } else {
+ return Err("stack is empty".to_string());
+ }
+ } else {
+ return Err("bad variable name in %P".to_string());
+ }
+ }
+ GetVar => {
+ if cur >= 'A' && cur <= 'Z' {
+ let idx = (cur as u8) - b'A';
+ stack.push(vars.sta_va[idx as usize].clone());
+ } else if cur >= 'a' && cur <= 'z' {
+ let idx = (cur as u8) - b'a';
+ stack.push(vars.dyn_va[idx as usize].clone());
+ } else {
+ return Err("bad variable name in %g".to_string());
+ }
+ }
+ CharConstant => {
+ stack.push(Number(c as i32));
+ state = CharClose;
+ }
+ CharClose => {
+ if cur != '\'' {
+ return Err("malformed character constant".to_string());
+ }
+ }
+ IntConstant(i) => {
+ if cur == '}' {
+ stack.push(Number(i));
+ state = Nothing;
+ } else if let Some(digit) = cur.to_digit(10) {
+ match i.checked_mul(10).and_then(|i_ten| i_ten.checked_add(digit as i32)) {
+ Some(i) => {
+ state = IntConstant(i);
+ old_state = Nothing;
+ }
+ None => return Err("int constant too large".to_string()),
+ }
+ } else {
+ return Err("bad int constant".to_string());
+ }
+ }
+ FormatPattern(ref mut flags, ref mut fstate) => {
+ old_state = Nothing;
+ match (*fstate, cur) {
+ (_, 'd') | (_, 'o') | (_, 'x') | (_, 'X') | (_, 's') => {
+ if let Some(arg) = stack.pop() {
+ let res = format(arg, FormatOp::from_char(cur), *flags)?;
+ output.extend(res.iter().cloned());
+ // will cause state to go to Nothing
+ old_state = FormatPattern(*flags, *fstate);
+ } else {
+ return Err("stack is empty".to_string());
+ }
+ }
+ (FormatState::Flags, '#') => {
+ flags.alternate = true;
+ }
+ (FormatState::Flags, '-') => {
+ flags.left = true;
+ }
+ (FormatState::Flags, '+') => {
+ flags.sign = true;
+ }
+ (FormatState::Flags, ' ') => {
+ flags.space = true;
+ }
+ (FormatState::Flags, '0'..='9') => {
+ flags.width = cur as usize - '0' as usize;
+ *fstate = FormatState::Width;
+ }
+ (FormatState::Flags, '.') => {
+ *fstate = FormatState::Precision;
+ }
+ (FormatState::Width, '0'..='9') => {
+ let old = flags.width;
+ flags.width = flags.width * 10 + (cur as usize - '0' as usize);
+ if flags.width < old {
+ return Err("format width overflow".to_string());
+ }
+ }
+ (FormatState::Width, '.') => {
+ *fstate = FormatState::Precision;
+ }
+ (FormatState::Precision, '0'..='9') => {
+ let old = flags.precision;
+ flags.precision = flags.precision * 10 + (cur as usize - '0' as usize);
+ if flags.precision < old {
+ return Err("format precision overflow".to_string());
+ }
+ }
+ _ => return Err("invalid format specifier".to_string()),
+ }
+ }
+ SeekIfElse(level) => {
+ if cur == '%' {
+ state = SeekIfElsePercent(level);
+ }
+ old_state = Nothing;
+ }
+ SeekIfElsePercent(level) => {
+ if cur == ';' {
+ if level == 0 {
+ state = Nothing;
+ } else {
+ state = SeekIfElse(level - 1);
+ }
+ } else if cur == 'e' && level == 0 {
+ state = Nothing;
+ } else if cur == '?' {
+ state = SeekIfElse(level + 1);
+ } else {
+ state = SeekIfElse(level);
+ }
+ }
+ SeekIfEnd(level) => {
+ if cur == '%' {
+ state = SeekIfEndPercent(level);
+ }
+ old_state = Nothing;
+ }
+ SeekIfEndPercent(level) => {
+ if cur == ';' {
+ if level == 0 {
+ state = Nothing;
+ } else {
+ state = SeekIfEnd(level - 1);
+ }
+ } else if cur == '?' {
+ state = SeekIfEnd(level + 1);
+ } else {
+ state = SeekIfEnd(level);
+ }
+ }
+ }
+ if state == old_state {
+ state = Nothing;
+ }
+ }
+ Ok(output)
+}
+
+#[derive(Copy, PartialEq, Clone)]
+struct Flags {
+ width: usize,
+ precision: usize,
+ alternate: bool,
+ left: bool,
+ sign: bool,
+ space: bool,
+}
+
+impl Flags {
+ fn new() -> Flags {
+ Flags { width: 0, precision: 0, alternate: false, left: false, sign: false, space: false }
+ }
+}
+
+#[derive(Copy, Clone)]
+enum FormatOp {
+ Digit,
+ Octal,
+ LowerHex,
+ UpperHex,
+ String,
+}
+
+impl FormatOp {
+ fn from_char(c: char) -> FormatOp {
+ match c {
+ 'd' => FormatOp::Digit,
+ 'o' => FormatOp::Octal,
+ 'x' => FormatOp::LowerHex,
+ 'X' => FormatOp::UpperHex,
+ 's' => FormatOp::String,
+ _ => panic!("bad FormatOp char"),
+ }
+ }
+}
+
+fn format(val: Param, op: FormatOp, flags: Flags) -> Result<Vec<u8>, String> {
+ let mut s = match val {
+ Number(d) => {
+ match op {
+ FormatOp::Digit => {
+ if flags.sign {
+ format!("{:+01$}", d, flags.precision)
+ } else if d < 0 {
+ // C doesn't take sign into account in precision calculation.
+ format!("{:01$}", d, flags.precision + 1)
+ } else if flags.space {
+ format!(" {:01$}", d, flags.precision)
+ } else {
+ format!("{:01$}", d, flags.precision)
+ }
+ }
+ FormatOp::Octal => {
+ if flags.alternate {
+ // Leading octal zero counts against precision.
+ format!("0{:01$o}", d, flags.precision.saturating_sub(1))
+ } else {
+ format!("{:01$o}", d, flags.precision)
+ }
+ }
+ FormatOp::LowerHex => {
+ if flags.alternate && d != 0 {
+ format!("0x{:01$x}", d, flags.precision)
+ } else {
+ format!("{:01$x}", d, flags.precision)
+ }
+ }
+ FormatOp::UpperHex => {
+ if flags.alternate && d != 0 {
+ format!("0X{:01$X}", d, flags.precision)
+ } else {
+ format!("{:01$X}", d, flags.precision)
+ }
+ }
+ FormatOp::String => return Err("non-number on stack with %s".to_string()),
+ }
+ .into_bytes()
+ }
+ };
+ if flags.width > s.len() {
+ let n = flags.width - s.len();
+ if flags.left {
+ s.extend(repeat(b' ').take(n));
+ } else {
+ let mut s_ = Vec::with_capacity(flags.width);
+ s_.extend(repeat(b' ').take(n));
+ s_.extend(s.into_iter());
+ s = s_;
+ }
+ }
+ Ok(s)
+}
--- /dev/null
+use super::*;
+
+use std::result::Result::Ok;
+
+#[test]
+fn test_basic_setabf() {
+ let s = b"\\E[48;5;%p1%dm";
+ assert_eq!(
+ expand(s, &[Number(1)], &mut Variables::new()).unwrap(),
+ "\\E[48;5;1m".bytes().collect::<Vec<_>>()
+ );
+}
+
+#[test]
+fn test_multiple_int_constants() {
+ assert_eq!(
+ expand(b"%{1}%{2}%d%d", &[], &mut Variables::new()).unwrap(),
+ "21".bytes().collect::<Vec<_>>()
+ );
+}
+
+#[test]
+fn test_op_i() {
+ let mut vars = Variables::new();
+ assert_eq!(
+ expand(b"%p1%d%p2%d%p3%d%i%p1%d%p2%d%p3%d", &[Number(1), Number(2), Number(3)], &mut vars),
+ Ok("123233".bytes().collect::<Vec<_>>())
+ );
+ assert_eq!(
+ expand(b"%p1%d%p2%d%i%p1%d%p2%d", &[], &mut vars),
+ Ok("0011".bytes().collect::<Vec<_>>())
+ );
+}
+
+#[test]
+fn test_param_stack_failure_conditions() {
+ let mut varstruct = Variables::new();
+ let vars = &mut varstruct;
+ fn get_res(
+ fmt: &str,
+ cap: &str,
+ params: &[Param],
+ vars: &mut Variables,
+ ) -> Result<Vec<u8>, String> {
+ let mut u8v: Vec<_> = fmt.bytes().collect();
+ u8v.extend(cap.as_bytes().iter().map(|&b| b));
+ expand(&u8v, params, vars)
+ }
+
+ let caps = ["%d", "%c", "%s", "%Pa", "%l", "%!", "%~"];
+ for &cap in caps.iter() {
+ let res = get_res("", cap, &[], vars);
+ assert!(res.is_err(), "Op {} succeeded incorrectly with 0 stack entries", cap);
+ if cap == "%s" || cap == "%l" {
+ continue;
+ }
+ let p = Number(97);
+ let res = get_res("%p1", cap, &[p], vars);
+ assert!(res.is_ok(), "Op {} failed with 1 stack entry: {}", cap, res.unwrap_err());
+ }
+ let caps = ["%+", "%-", "%*", "%/", "%m", "%&", "%|", "%A", "%O"];
+ for &cap in caps.iter() {
+ let res = expand(cap.as_bytes(), &[], vars);
+ assert!(res.is_err(), "Binop {} succeeded incorrectly with 0 stack entries", cap);
+ let res = get_res("%{1}", cap, &[], vars);
+ assert!(res.is_err(), "Binop {} succeeded incorrectly with 1 stack entry", cap);
+ let res = get_res("%{1}%{2}", cap, &[], vars);
+ assert!(res.is_ok(), "Binop {} failed with 2 stack entries: {}", cap, res.unwrap_err());
+ }
+}
+
+#[test]
+fn test_push_bad_param() {
+ assert!(expand(b"%pa", &[], &mut Variables::new()).is_err());
+}
+
+#[test]
+fn test_comparison_ops() {
+ let v = [('<', [1u8, 0u8, 0u8]), ('=', [0u8, 1u8, 0u8]), ('>', [0u8, 0u8, 1u8])];
+ for &(op, bs) in v.iter() {
+ let s = format!("%{{1}}%{{2}}%{}%d", op);
+ let res = expand(s.as_bytes(), &[], &mut Variables::new());
+ assert!(res.is_ok(), "{}", res.unwrap_err());
+ assert_eq!(res.unwrap(), vec![b'0' + bs[0]]);
+ let s = format!("%{{1}}%{{1}}%{}%d", op);
+ let res = expand(s.as_bytes(), &[], &mut Variables::new());
+ assert!(res.is_ok(), "{}", res.unwrap_err());
+ assert_eq!(res.unwrap(), vec![b'0' + bs[1]]);
+ let s = format!("%{{2}}%{{1}}%{}%d", op);
+ let res = expand(s.as_bytes(), &[], &mut Variables::new());
+ assert!(res.is_ok(), "{}", res.unwrap_err());
+ assert_eq!(res.unwrap(), vec![b'0' + bs[2]]);
+ }
+}
+
+#[test]
+fn test_conditionals() {
+ let mut vars = Variables::new();
+ let s = b"\\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m";
+ let res = expand(s, &[Number(1)], &mut vars);
+ assert!(res.is_ok(), "{}", res.unwrap_err());
+ assert_eq!(res.unwrap(), "\\E[31m".bytes().collect::<Vec<_>>());
+ let res = expand(s, &[Number(8)], &mut vars);
+ assert!(res.is_ok(), "{}", res.unwrap_err());
+ assert_eq!(res.unwrap(), "\\E[90m".bytes().collect::<Vec<_>>());
+ let res = expand(s, &[Number(42)], &mut vars);
+ assert!(res.is_ok(), "{}", res.unwrap_err());
+ assert_eq!(res.unwrap(), "\\E[38;5;42m".bytes().collect::<Vec<_>>());
+}
+
+#[test]
+fn test_format() {
+ let mut varstruct = Variables::new();
+ let vars = &mut varstruct;
+
+ assert_eq!(
+ expand(b"%p1%d%p1%.3d%p1%5d%p1%:+d", &[Number(1)], vars),
+ Ok("1001 1+1".bytes().collect::<Vec<_>>())
+ );
+ assert_eq!(
+ expand(b"%p1%o%p1%#o%p2%6.4x%p2%#6.4X", &[Number(15), Number(27)], vars),
+ Ok("17017 001b0X001B".bytes().collect::<Vec<_>>())
+ );
+}
--- /dev/null
+#![allow(non_upper_case_globals, missing_docs)]
+
+//! ncurses-compatible compiled terminfo format parsing (term(5))
+
+use super::super::TermInfo;
+use std::collections::HashMap;
+use std::io;
+use std::io::prelude::*;
+
+#[cfg(test)]
+mod tests;
+
+// These are the orders ncurses uses in its compiled format (as of 5.9). Not sure if portable.
+
+#[rustfmt::skip]
+pub(crate) static boolfnames: &[&str] = &["auto_left_margin", "auto_right_margin",
+ "no_esc_ctlc", "ceol_standout_glitch", "eat_newline_glitch", "erase_overstrike", "generic_type",
+ "hard_copy", "has_meta_key", "has_status_line", "insert_null_glitch", "memory_above",
+ "memory_below", "move_insert_mode", "move_standout_mode", "over_strike", "status_line_esc_ok",
+ "dest_tabs_magic_smso", "tilde_glitch", "transparent_underline", "xon_xoff", "needs_xon_xoff",
+ "prtr_silent", "hard_cursor", "non_rev_rmcup", "no_pad_char", "non_dest_scroll_region",
+ "can_change", "back_color_erase", "hue_lightness_saturation", "col_addr_glitch",
+ "cr_cancels_micro_mode", "has_print_wheel", "row_addr_glitch", "semi_auto_right_margin",
+ "cpi_changes_res", "lpi_changes_res", "backspaces_with_bs", "crt_no_scrolling",
+ "no_correctly_working_cr", "gnu_has_meta_key", "linefeed_is_newline", "has_hardware_tabs",
+ "return_does_clr_eol"];
+
+#[rustfmt::skip]
+pub(crate) static boolnames: &[&str] = &["bw", "am", "xsb", "xhp", "xenl", "eo",
+ "gn", "hc", "km", "hs", "in", "db", "da", "mir", "msgr", "os", "eslok", "xt", "hz", "ul", "xon",
+ "nxon", "mc5i", "chts", "nrrmc", "npc", "ndscr", "ccc", "bce", "hls", "xhpa", "crxm", "daisy",
+ "xvpa", "sam", "cpix", "lpix", "OTbs", "OTns", "OTnc", "OTMT", "OTNL", "OTpt", "OTxr"];
+
+#[rustfmt::skip]
+pub(crate) static numfnames: &[&str] = &[ "columns", "init_tabs", "lines",
+ "lines_of_memory", "magic_cookie_glitch", "padding_baud_rate", "virtual_terminal",
+ "width_status_line", "num_labels", "label_height", "label_width", "max_attributes",
+ "maximum_windows", "max_colors", "max_pairs", "no_color_video", "buffer_capacity",
+ "dot_vert_spacing", "dot_horz_spacing", "max_micro_address", "max_micro_jump", "micro_col_size",
+ "micro_line_size", "number_of_pins", "output_res_char", "output_res_line",
+ "output_res_horz_inch", "output_res_vert_inch", "print_rate", "wide_char_size", "buttons",
+ "bit_image_entwining", "bit_image_type", "magic_cookie_glitch_ul", "carriage_return_delay",
+ "new_line_delay", "backspace_delay", "horizontal_tab_delay", "number_of_function_keys"];
+
+#[rustfmt::skip]
+pub(crate) static numnames: &[&str] = &[ "cols", "it", "lines", "lm", "xmc", "pb",
+ "vt", "wsl", "nlab", "lh", "lw", "ma", "wnum", "colors", "pairs", "ncv", "bufsz", "spinv",
+ "spinh", "maddr", "mjump", "mcs", "mls", "npins", "orc", "orl", "orhi", "orvi", "cps", "widcs",
+ "btns", "bitwin", "bitype", "UTug", "OTdC", "OTdN", "OTdB", "OTdT", "OTkn"];
+
+#[rustfmt::skip]
+pub(crate) static stringfnames: &[&str] = &[ "back_tab", "bell", "carriage_return",
+ "change_scroll_region", "clear_all_tabs", "clear_screen", "clr_eol", "clr_eos",
+ "column_address", "command_character", "cursor_address", "cursor_down", "cursor_home",
+ "cursor_invisible", "cursor_left", "cursor_mem_address", "cursor_normal", "cursor_right",
+ "cursor_to_ll", "cursor_up", "cursor_visible", "delete_character", "delete_line",
+ "dis_status_line", "down_half_line", "enter_alt_charset_mode", "enter_blink_mode",
+ "enter_bold_mode", "enter_ca_mode", "enter_delete_mode", "enter_dim_mode", "enter_insert_mode",
+ "enter_secure_mode", "enter_protected_mode", "enter_reverse_mode", "enter_standout_mode",
+ "enter_underline_mode", "erase_chars", "exit_alt_charset_mode", "exit_attribute_mode",
+ "exit_ca_mode", "exit_delete_mode", "exit_insert_mode", "exit_standout_mode",
+ "exit_underline_mode", "flash_screen", "form_feed", "from_status_line", "init_1string",
+ "init_2string", "init_3string", "init_file", "insert_character", "insert_line",
+ "insert_padding", "key_backspace", "key_catab", "key_clear", "key_ctab", "key_dc", "key_dl",
+ "key_down", "key_eic", "key_eol", "key_eos", "key_f0", "key_f1", "key_f10", "key_f2", "key_f3",
+ "key_f4", "key_f5", "key_f6", "key_f7", "key_f8", "key_f9", "key_home", "key_ic", "key_il",
+ "key_left", "key_ll", "key_npage", "key_ppage", "key_right", "key_sf", "key_sr", "key_stab",
+ "key_up", "keypad_local", "keypad_xmit", "lab_f0", "lab_f1", "lab_f10", "lab_f2", "lab_f3",
+ "lab_f4", "lab_f5", "lab_f6", "lab_f7", "lab_f8", "lab_f9", "meta_off", "meta_on", "newline",
+ "pad_char", "parm_dch", "parm_delete_line", "parm_down_cursor", "parm_ich", "parm_index",
+ "parm_insert_line", "parm_left_cursor", "parm_right_cursor", "parm_rindex", "parm_up_cursor",
+ "pkey_key", "pkey_local", "pkey_xmit", "print_screen", "prtr_off", "prtr_on", "repeat_char",
+ "reset_1string", "reset_2string", "reset_3string", "reset_file", "restore_cursor",
+ "row_address", "save_cursor", "scroll_forward", "scroll_reverse", "set_attributes", "set_tab",
+ "set_window", "tab", "to_status_line", "underline_char", "up_half_line", "init_prog", "key_a1",
+ "key_a3", "key_b2", "key_c1", "key_c3", "prtr_non", "char_padding", "acs_chars", "plab_norm",
+ "key_btab", "enter_xon_mode", "exit_xon_mode", "enter_am_mode", "exit_am_mode", "xon_character",
+ "xoff_character", "ena_acs", "label_on", "label_off", "key_beg", "key_cancel", "key_close",
+ "key_command", "key_copy", "key_create", "key_end", "key_enter", "key_exit", "key_find",
+ "key_help", "key_mark", "key_message", "key_move", "key_next", "key_open", "key_options",
+ "key_previous", "key_print", "key_redo", "key_reference", "key_refresh", "key_replace",
+ "key_restart", "key_resume", "key_save", "key_suspend", "key_undo", "key_sbeg", "key_scancel",
+ "key_scommand", "key_scopy", "key_screate", "key_sdc", "key_sdl", "key_select", "key_send",
+ "key_seol", "key_sexit", "key_sfind", "key_shelp", "key_shome", "key_sic", "key_sleft",
+ "key_smessage", "key_smove", "key_snext", "key_soptions", "key_sprevious", "key_sprint",
+ "key_sredo", "key_sreplace", "key_sright", "key_srsume", "key_ssave", "key_ssuspend",
+ "key_sundo", "req_for_input", "key_f11", "key_f12", "key_f13", "key_f14", "key_f15", "key_f16",
+ "key_f17", "key_f18", "key_f19", "key_f20", "key_f21", "key_f22", "key_f23", "key_f24",
+ "key_f25", "key_f26", "key_f27", "key_f28", "key_f29", "key_f30", "key_f31", "key_f32",
+ "key_f33", "key_f34", "key_f35", "key_f36", "key_f37", "key_f38", "key_f39", "key_f40",
+ "key_f41", "key_f42", "key_f43", "key_f44", "key_f45", "key_f46", "key_f47", "key_f48",
+ "key_f49", "key_f50", "key_f51", "key_f52", "key_f53", "key_f54", "key_f55", "key_f56",
+ "key_f57", "key_f58", "key_f59", "key_f60", "key_f61", "key_f62", "key_f63", "clr_bol",
+ "clear_margins", "set_left_margin", "set_right_margin", "label_format", "set_clock",
+ "display_clock", "remove_clock", "create_window", "goto_window", "hangup", "dial_phone",
+ "quick_dial", "tone", "pulse", "flash_hook", "fixed_pause", "wait_tone", "user0", "user1",
+ "user2", "user3", "user4", "user5", "user6", "user7", "user8", "user9", "orig_pair",
+ "orig_colors", "initialize_color", "initialize_pair", "set_color_pair", "set_foreground",
+ "set_background", "change_char_pitch", "change_line_pitch", "change_res_horz",
+ "change_res_vert", "define_char", "enter_doublewide_mode", "enter_draft_quality",
+ "enter_italics_mode", "enter_leftward_mode", "enter_micro_mode", "enter_near_letter_quality",
+ "enter_normal_quality", "enter_shadow_mode", "enter_subscript_mode", "enter_superscript_mode",
+ "enter_upward_mode", "exit_doublewide_mode", "exit_italics_mode", "exit_leftward_mode",
+ "exit_micro_mode", "exit_shadow_mode", "exit_subscript_mode", "exit_superscript_mode",
+ "exit_upward_mode", "micro_column_address", "micro_down", "micro_left", "micro_right",
+ "micro_row_address", "micro_up", "order_of_pins", "parm_down_micro", "parm_left_micro",
+ "parm_right_micro", "parm_up_micro", "select_char_set", "set_bottom_margin",
+ "set_bottom_margin_parm", "set_left_margin_parm", "set_right_margin_parm", "set_top_margin",
+ "set_top_margin_parm", "start_bit_image", "start_char_set_def", "stop_bit_image",
+ "stop_char_set_def", "subscript_characters", "superscript_characters", "these_cause_cr",
+ "zero_motion", "char_set_names", "key_mouse", "mouse_info", "req_mouse_pos", "get_mouse",
+ "set_a_foreground", "set_a_background", "pkey_plab", "device_type", "code_set_init",
+ "set0_des_seq", "set1_des_seq", "set2_des_seq", "set3_des_seq", "set_lr_margin",
+ "set_tb_margin", "bit_image_repeat", "bit_image_newline", "bit_image_carriage_return",
+ "color_names", "define_bit_image_region", "end_bit_image_region", "set_color_band",
+ "set_page_length", "display_pc_char", "enter_pc_charset_mode", "exit_pc_charset_mode",
+ "enter_scancode_mode", "exit_scancode_mode", "pc_term_options", "scancode_escape",
+ "alt_scancode_esc", "enter_horizontal_hl_mode", "enter_left_hl_mode", "enter_low_hl_mode",
+ "enter_right_hl_mode", "enter_top_hl_mode", "enter_vertical_hl_mode", "set_a_attributes",
+ "set_pglen_inch", "termcap_init2", "termcap_reset", "linefeed_if_not_lf", "backspace_if_not_bs",
+ "other_non_function_keys", "arrow_key_map", "acs_ulcorner", "acs_llcorner", "acs_urcorner",
+ "acs_lrcorner", "acs_ltee", "acs_rtee", "acs_btee", "acs_ttee", "acs_hline", "acs_vline",
+ "acs_plus", "memory_lock", "memory_unlock", "box_chars_1"];
+
+#[rustfmt::skip]
+pub(crate) static stringnames: &[&str] = &[ "cbt", "_", "cr", "csr", "tbc", "clear",
+ "_", "_", "hpa", "cmdch", "cup", "cud1", "home", "civis", "cub1", "mrcup", "cnorm", "cuf1",
+ "ll", "cuu1", "cvvis", "dch1", "dl1", "dsl", "hd", "smacs", "blink", "bold", "smcup", "smdc",
+ "dim", "smir", "invis", "prot", "rev", "smso", "smul", "ech", "rmacs", "sgr0", "rmcup", "rmdc",
+ "rmir", "rmso", "rmul", "flash", "ff", "fsl", "is1", "is2", "is3", "if", "ich1", "il1", "ip",
+ "kbs", "ktbc", "kclr", "kctab", "_", "_", "kcud1", "_", "_", "_", "_", "_", "_", "_", "_", "_",
+ "_", "_", "_", "_", "_", "khome", "_", "_", "kcub1", "_", "knp", "kpp", "kcuf1", "_", "_",
+ "khts", "_", "rmkx", "smkx", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "rmm", "_",
+ "_", "pad", "dch", "dl", "cud", "ich", "indn", "il", "cub", "cuf", "rin", "cuu", "pfkey",
+ "pfloc", "pfx", "mc0", "mc4", "_", "rep", "rs1", "rs2", "rs3", "rf", "rc", "vpa", "sc", "ind",
+ "ri", "sgr", "_", "wind", "_", "tsl", "uc", "hu", "iprog", "_", "_", "_", "_", "_", "mc5p",
+ "rmp", "acsc", "pln", "kcbt", "smxon", "rmxon", "smam", "rmam", "xonc", "xoffc", "_", "smln",
+ "rmln", "_", "kcan", "kclo", "kcmd", "kcpy", "kcrt", "_", "kent", "kext", "kfnd", "khlp",
+ "kmrk", "kmsg", "kmov", "knxt", "kopn", "kopt", "kprv", "kprt", "krdo", "kref", "krfr", "krpl",
+ "krst", "kres", "ksav", "kspd", "kund", "kBEG", "kCAN", "kCMD", "kCPY", "kCRT", "_", "_",
+ "kslt", "kEND", "kEOL", "kEXT", "kFND", "kHLP", "kHOM", "_", "kLFT", "kMSG", "kMOV", "kNXT",
+ "kOPT", "kPRV", "kPRT", "kRDO", "kRPL", "kRIT", "kRES", "kSAV", "kSPD", "kUND", "rfi", "_", "_",
+ "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_",
+ "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_",
+ "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_",
+ "dclk", "rmclk", "cwin", "wingo", "_", "dial", "qdial", "_", "_", "hook", "pause", "wait", "_",
+ "_", "_", "_", "_", "_", "_", "_", "_", "_", "op", "oc", "initc", "initp", "scp", "setf",
+ "setb", "cpi", "lpi", "chr", "cvr", "defc", "swidm", "sdrfq", "sitm", "slm", "smicm", "snlq",
+ "snrmq", "sshm", "ssubm", "ssupm", "sum", "rwidm", "ritm", "rlm", "rmicm", "rshm", "rsubm",
+ "rsupm", "rum", "mhpa", "mcud1", "mcub1", "mcuf1", "mvpa", "mcuu1", "porder", "mcud", "mcub",
+ "mcuf", "mcuu", "scs", "smgb", "smgbp", "smglp", "smgrp", "smgt", "smgtp", "sbim", "scsd",
+ "rbim", "rcsd", "subcs", "supcs", "docr", "zerom", "csnm", "kmous", "minfo", "reqmp", "getm",
+ "setaf", "setab", "pfxl", "devt", "csin", "s0ds", "s1ds", "s2ds", "s3ds", "smglr", "smgtb",
+ "birep", "binel", "bicr", "colornm", "defbi", "endbi", "setcolor", "slines", "dispc", "smpch",
+ "rmpch", "smsc", "rmsc", "pctrm", "scesc", "scesa", "ehhlm", "elhlm", "elohlm", "erhlm",
+ "ethlm", "evhlm", "sgr1", "slength", "OTi2", "OTrs", "OTnl", "OTbs", "OTko", "OTma", "OTG2",
+ "OTG3", "OTG1", "OTG4", "OTGR", "OTGL", "OTGU", "OTGD", "OTGH", "OTGV", "OTGC", "meml", "memu",
+ "box1"];
+
+fn read_le_u16(r: &mut dyn io::Read) -> io::Result<u16> {
+ let mut b = [0; 2];
+ r.read_exact(&mut b)?;
+ Ok((b[0] as u16) | ((b[1] as u16) << 8))
+}
+
+fn read_le_u32(r: &mut dyn io::Read) -> io::Result<u32> {
+ let mut b = [0; 4];
+ r.read_exact(&mut b)?;
+ Ok((b[0] as u32) | ((b[1] as u32) << 8) | ((b[2] as u32) << 16) | ((b[3] as u32) << 24))
+}
+
+fn read_byte(r: &mut dyn io::Read) -> io::Result<u8> {
+ match r.bytes().next() {
+ Some(s) => s,
+ None => Err(io::Error::new(io::ErrorKind::Other, "end of file")),
+ }
+}
+
+/// Parse a compiled terminfo entry, using long capability names if `longnames`
+/// is true
+pub(crate) fn parse(file: &mut dyn io::Read, longnames: bool) -> Result<TermInfo, String> {
+ macro_rules! t( ($e:expr) => (
+ match $e {
+ Ok(e) => e,
+ Err(e) => return Err(e.to_string())
+ }
+ ) );
+
+ let (bnames, snames, nnames) = if longnames {
+ (boolfnames, stringfnames, numfnames)
+ } else {
+ (boolnames, stringnames, numnames)
+ };
+
+ // Check magic number
+ let magic = t!(read_le_u16(file));
+
+ let extended = match magic {
+ 0o0432 => false,
+ 0o01036 => true,
+ _ => return Err(format!("invalid magic number, found {:o}", magic)),
+ };
+
+ // According to the spec, these fields must be >= -1 where -1 means that the feature is not
+ // supported. Using 0 instead of -1 works because we skip sections with length 0.
+ macro_rules! read_nonneg {
+ () => {{
+ match t!(read_le_u16(file)) as i16 {
+ n if n >= 0 => n as usize,
+ -1 => 0,
+ _ => return Err("incompatible file: length fields must be >= -1".to_string()),
+ }
+ }};
+ }
+
+ let names_bytes = read_nonneg!();
+ let bools_bytes = read_nonneg!();
+ let numbers_count = read_nonneg!();
+ let string_offsets_count = read_nonneg!();
+ let string_table_bytes = read_nonneg!();
+
+ if names_bytes == 0 {
+ return Err("incompatible file: names field must be at least 1 byte wide".to_string());
+ }
+
+ if bools_bytes > boolnames.len() {
+ return Err("incompatible file: more booleans than expected".to_string());
+ }
+
+ if numbers_count > numnames.len() {
+ return Err("incompatible file: more numbers than expected".to_string());
+ }
+
+ if string_offsets_count > stringnames.len() {
+ return Err("incompatible file: more string offsets than expected".to_string());
+ }
+
+ // don't read NUL
+ let mut bytes = Vec::new();
+ t!(file.take((names_bytes - 1) as u64).read_to_end(&mut bytes));
+ let names_str = match String::from_utf8(bytes) {
+ Ok(s) => s,
+ Err(_) => return Err("input not utf-8".to_string()),
+ };
+
+ let term_names: Vec<String> = names_str.split('|').map(|s| s.to_string()).collect();
+ // consume NUL
+ if t!(read_byte(file)) != b'\0' {
+ return Err("incompatible file: missing null terminator for names section".to_string());
+ }
+
+ let bools_map: HashMap<String, bool> = t! {
+ (0..bools_bytes).filter_map(|i| match read_byte(file) {
+ Err(e) => Some(Err(e)),
+ Ok(1) => Some(Ok((bnames[i].to_string(), true))),
+ Ok(_) => None
+ }).collect()
+ };
+
+ if (bools_bytes + names_bytes) % 2 == 1 {
+ t!(read_byte(file)); // compensate for padding
+ }
+
+ let numbers_map: HashMap<String, u32> = t! {
+ (0..numbers_count).filter_map(|i| {
+ let number = if extended { read_le_u32(file) } else { read_le_u16(file).map(Into::into) };
+
+ match number {
+ Ok(0xFFFF) => None,
+ Ok(n) => Some(Ok((nnames[i].to_string(), n))),
+ Err(e) => Some(Err(e))
+ }
+ }).collect()
+ };
+
+ let string_map: HashMap<String, Vec<u8>> = if string_offsets_count > 0 {
+ let string_offsets: Vec<u16> =
+ t!((0..string_offsets_count).map(|_| read_le_u16(file)).collect());
+
+ let mut string_table = Vec::new();
+ t!(file.take(string_table_bytes as u64).read_to_end(&mut string_table));
+
+ t!(string_offsets
+ .into_iter()
+ .enumerate()
+ .filter(|&(_, offset)| {
+ // non-entry
+ offset != 0xFFFF
+ })
+ .map(|(i, offset)| {
+ let offset = offset as usize;
+
+ let name = if snames[i] == "_" { stringfnames[i] } else { snames[i] };
+
+ if offset == 0xFFFE {
+ // undocumented: FFFE indicates cap@, which means the capability is not present
+ // unsure if the handling for this is correct
+ return Ok((name.to_string(), Vec::new()));
+ }
+
+ // Find the offset of the NUL we want to go to
+ let nulpos = string_table[offset..string_table_bytes].iter().position(|&b| b == 0);
+ match nulpos {
+ Some(len) => {
+ Ok((name.to_string(), string_table[offset..offset + len].to_vec()))
+ }
+ None => Err("invalid file: missing NUL in string_table".to_string()),
+ }
+ })
+ .collect())
+ } else {
+ HashMap::new()
+ };
+
+ // And that's all there is to it
+ Ok(TermInfo { names: term_names, bools: bools_map, numbers: numbers_map, strings: string_map })
+}
+
+/// Creates a dummy TermInfo struct for msys terminals
+pub(crate) fn msys_terminfo() -> TermInfo {
+ let mut strings = HashMap::new();
+ strings.insert("sgr0".to_string(), b"\x1B[0m".to_vec());
+ strings.insert("bold".to_string(), b"\x1B[1m".to_vec());
+ strings.insert("setaf".to_string(), b"\x1B[3%p1%dm".to_vec());
+ strings.insert("setab".to_string(), b"\x1B[4%p1%dm".to_vec());
+
+ let mut numbers = HashMap::new();
+ numbers.insert("colors".to_string(), 8);
+
+ TermInfo {
+ names: vec!["cygwin".to_string()], // msys is a fork of an older cygwin version
+ bools: HashMap::new(),
+ numbers,
+ strings,
+ }
+}
--- /dev/null
+use super::*;
+
+#[test]
+fn test_veclens() {
+ assert_eq!(boolfnames.len(), boolnames.len());
+ assert_eq!(numfnames.len(), numnames.len());
+ assert_eq!(stringfnames.len(), stringnames.len());
+}
--- /dev/null
+//! ncurses-compatible database discovery.
+//!
+//! Does not support hashed database, only filesystem!
+
+use std::env;
+use std::fs;
+use std::path::PathBuf;
+
+#[cfg(test)]
+mod tests;
+
+/// Return path to database entry for `term`
+#[allow(deprecated)]
+pub(crate) fn get_dbpath_for_term(term: &str) -> Option<PathBuf> {
+ let mut dirs_to_search = Vec::new();
+ let first_char = term.chars().next()?;
+
+ // Find search directory
+ if let Some(dir) = env::var_os("TERMINFO") {
+ dirs_to_search.push(PathBuf::from(dir));
+ }
+
+ if let Ok(dirs) = env::var("TERMINFO_DIRS") {
+ for i in dirs.split(':') {
+ if i == "" {
+ dirs_to_search.push(PathBuf::from("/usr/share/terminfo"));
+ } else {
+ dirs_to_search.push(PathBuf::from(i));
+ }
+ }
+ } else {
+ // Found nothing in TERMINFO_DIRS, use the default paths:
+ // According to /etc/terminfo/README, after looking at
+ // ~/.terminfo, ncurses will search /etc/terminfo, then
+ // /lib/terminfo, and eventually /usr/share/terminfo.
+ // On Haiku the database can be found at /boot/system/data/terminfo
+ if let Some(mut homedir) = env::home_dir() {
+ homedir.push(".terminfo");
+ dirs_to_search.push(homedir)
+ }
+
+ dirs_to_search.push(PathBuf::from("/etc/terminfo"));
+ dirs_to_search.push(PathBuf::from("/lib/terminfo"));
+ dirs_to_search.push(PathBuf::from("/usr/share/terminfo"));
+ dirs_to_search.push(PathBuf::from("/boot/system/data/terminfo"));
+ }
+
+ // Look for the terminal in all of the search directories
+ for mut p in dirs_to_search {
+ if fs::metadata(&p).is_ok() {
+ p.push(&first_char.to_string());
+ p.push(&term);
+ if fs::metadata(&p).is_ok() {
+ return Some(p);
+ }
+ p.pop();
+ p.pop();
+
+ // on some installations the dir is named after the hex of the char
+ // (e.g., macOS)
+ p.push(&format!("{:x}", first_char as usize));
+ p.push(term);
+ if fs::metadata(&p).is_ok() {
+ return Some(p);
+ }
+ }
+ }
+ None
+}
--- /dev/null
+use super::*;
+
+#[test]
+#[ignore = "buildbots don't have ncurses installed and I can't mock everything I need"]
+fn test_get_dbpath_for_term() {
+ // woefully inadequate test coverage
+ // note: current tests won't work with non-standard terminfo hierarchies (e.g., macOS's)
+ use std::env;
+ // FIXME (#9639): This needs to handle non-utf8 paths
+ fn x(t: &str) -> String {
+ let p = get_dbpath_for_term(t).expect("no terminfo entry found");
+ p.to_str().unwrap().to_string()
+ }
+ assert!(x("screen") == "/usr/share/terminfo/s/screen");
+ assert!(get_dbpath_for_term("") == None);
+ env::set_var("TERMINFO_DIRS", ":");
+ assert!(x("screen") == "/usr/share/terminfo/s/screen");
+ env::remove_var("TERMINFO_DIRS");
+}
--- /dev/null
+//! Windows console handling
+
+// FIXME (#13400): this is only a tiny fraction of the Windows console api
+
+use std::io;
+use std::io::prelude::*;
+
+use super::color;
+use super::Terminal;
+
+/// A Terminal implementation that uses the Win32 Console API.
+pub(crate) struct WinConsole<T> {
+ buf: T,
+ def_foreground: color::Color,
+ def_background: color::Color,
+ foreground: color::Color,
+ background: color::Color,
+}
+
+type SHORT = i16;
+type WORD = u16;
+type DWORD = u32;
+type BOOL = i32;
+type HANDLE = *mut u8;
+
+#[allow(non_snake_case)]
+#[repr(C)]
+struct SMALL_RECT {
+ Left: SHORT,
+ Top: SHORT,
+ Right: SHORT,
+ Bottom: SHORT,
+}
+
+#[allow(non_snake_case)]
+#[repr(C)]
+struct COORD {
+ X: SHORT,
+ Y: SHORT,
+}
+
+#[allow(non_snake_case)]
+#[repr(C)]
+struct CONSOLE_SCREEN_BUFFER_INFO {
+ dwSize: COORD,
+ dwCursorPosition: COORD,
+ wAttributes: WORD,
+ srWindow: SMALL_RECT,
+ dwMaximumWindowSize: COORD,
+}
+
+#[allow(non_snake_case)]
+#[link(name = "kernel32")]
+extern "system" {
+ fn SetConsoleTextAttribute(handle: HANDLE, attr: WORD) -> BOOL;
+ fn GetStdHandle(which: DWORD) -> HANDLE;
+ fn GetConsoleScreenBufferInfo(handle: HANDLE, info: *mut CONSOLE_SCREEN_BUFFER_INFO) -> BOOL;
+}
+
+fn color_to_bits(color: color::Color) -> u16 {
+ // magic numbers from mingw-w64's wincon.h
+
+ let bits = match color % 8 {
+ color::BLACK => 0,
+ color::BLUE => 0x1,
+ color::GREEN => 0x2,
+ color::RED => 0x4,
+ color::YELLOW => 0x2 | 0x4,
+ color::MAGENTA => 0x1 | 0x4,
+ color::CYAN => 0x1 | 0x2,
+ color::WHITE => 0x1 | 0x2 | 0x4,
+ _ => unreachable!(),
+ };
+
+ if color >= 8 { bits | 0x8 } else { bits }
+}
+
+fn bits_to_color(bits: u16) -> color::Color {
+ let color = match bits & 0x7 {
+ 0 => color::BLACK,
+ 0x1 => color::BLUE,
+ 0x2 => color::GREEN,
+ 0x4 => color::RED,
+ 0x6 => color::YELLOW,
+ 0x5 => color::MAGENTA,
+ 0x3 => color::CYAN,
+ 0x7 => color::WHITE,
+ _ => unreachable!(),
+ };
+
+ color | (u32::from(bits) & 0x8) // copy the hi-intensity bit
+}
+
+impl<T: Write + Send + 'static> WinConsole<T> {
+ fn apply(&mut self) {
+ let _unused = self.buf.flush();
+ let mut accum: WORD = 0;
+ accum |= color_to_bits(self.foreground);
+ accum |= color_to_bits(self.background) << 4;
+
+ unsafe {
+ // Magic -11 means stdout, from
+ // https://docs.microsoft.com/en-us/windows/console/getstdhandle
+ //
+ // You may be wondering, "but what about stderr?", and the answer
+ // to that is that setting terminal attributes on the stdout
+ // handle also sets them for stderr, since they go to the same
+ // terminal! Admittedly, this is fragile, since stderr could be
+ // redirected to a different console. This is good enough for
+ // rustc though. See #13400.
+ let out = GetStdHandle(-11i32 as DWORD);
+ SetConsoleTextAttribute(out, accum);
+ }
+ }
+
+ /// Returns `None` whenever the terminal cannot be created for some reason.
+ pub(crate) fn new(out: T) -> io::Result<WinConsole<T>> {
+ use std::mem::MaybeUninit;
+
+ let fg;
+ let bg;
+ unsafe {
+ let mut buffer_info = MaybeUninit::<CONSOLE_SCREEN_BUFFER_INFO>::uninit();
+ if GetConsoleScreenBufferInfo(GetStdHandle(-11i32 as DWORD), buffer_info.as_mut_ptr())
+ != 0
+ {
+ let buffer_info = buffer_info.assume_init();
+ fg = bits_to_color(buffer_info.wAttributes);
+ bg = bits_to_color(buffer_info.wAttributes >> 4);
+ } else {
+ fg = color::WHITE;
+ bg = color::BLACK;
+ }
+ }
+ Ok(WinConsole {
+ buf: out,
+ def_foreground: fg,
+ def_background: bg,
+ foreground: fg,
+ background: bg,
+ })
+ }
+}
+
+impl<T: Write> Write for WinConsole<T> {
+ fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+ self.buf.write(buf)
+ }
+
+ fn flush(&mut self) -> io::Result<()> {
+ self.buf.flush()
+ }
+}
+
+impl<T: Write + Send + 'static> Terminal for WinConsole<T> {
+ fn fg(&mut self, color: color::Color) -> io::Result<bool> {
+ self.foreground = color;
+ self.apply();
+
+ Ok(true)
+ }
+
+ fn reset(&mut self) -> io::Result<bool> {
+ self.foreground = self.def_foreground;
+ self.background = self.def_background;
+ self.apply();
+
+ Ok(true)
+ }
+}
if ostype != "Linux":
return
- if not os.path.exists("/etc/NIXOS"):
+ # Use `/etc/os-release` instead of `/etc/NIXOS`.
+ # The latter one does not exist on NixOS when using tmpfs as root.
+ try:
+ with open("/etc/os-release", "r") as f:
+ if not any(line.strip() == "ID=nixos" for line in f):
+ return
+ except FileNotFoundError:
return
if os.path.exists("/lib"):
return
slow_submodules = self.get_toml('fast-submodules') == "false"
start_time = time()
if slow_submodules:
- print('Unconditionally updating all submodules')
+ print('Unconditionally updating submodules')
else:
print('Updating only changed submodules')
default_encoding = sys.getdefaultencoding()
- submodules = [s.split(' ', 1)[1] for s in subprocess.check_output(
- ["git", "config", "--file",
- os.path.join(self.rust_root, ".gitmodules"),
- "--get-regexp", "path"]
- ).decode(default_encoding).splitlines()]
+ # Only update submodules that are needed to build bootstrap. These are needed because Cargo
+ # currently requires everything in a workspace to be "locally present" when starting a
+ # build, and will give a hard error if any Cargo.toml files are missing.
+ # FIXME: Is there a way to avoid cloning these eagerly? Bootstrap itself doesn't need to
+ # share a workspace with any tools - maybe it could be excluded from the workspace?
+ # That will still require cloning the submodules the second you check the standard
+ # library, though...
+ # FIXME: Is there a way to avoid hard-coding the submodules required?
+ # WARNING: keep this in sync with the submodules hard-coded in bootstrap/lib.rs
+ submodules = [
+ "src/tools/rust-installer",
+ "src/tools/cargo",
+ "src/tools/rls",
+ "src/tools/miri",
+ "library/backtrace",
+ "library/stdarch"
+ ]
filtered_submodules = []
submodules_names = []
for module in submodules:
- # This is handled by native::Llvm in rustbuild, not here
- if module.endswith("llvm-project"):
- continue
check = self.check_submodule(module, slow_submodules)
filtered_submodules.append((module, check))
submodules_names.append(module)
use crate::tool::{prepare_tool_cargo, SourceType};
use crate::INTERNER;
use crate::{Compiler, Mode, Subcommand};
-use std::path::PathBuf;
+use std::path::{Path, PathBuf};
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct Std {
}
fn run(self, builder: &Builder<'_>) {
+ builder.update_submodule(&Path::new("library").join("stdarch"));
+
let target = self.target;
let compiler = builder.compiler(builder.top_stage, builder.config.build);
//! library.
//!
//! This module contains some of the real meat in the rustbuild build system
-//! which is where Cargo is used to compiler the standard library, libtest, and
+//! which is where Cargo is used to compile the standard library, libtest, and
//! compiler. This module is also responsible for assembling the sysroot as it
//! goes along from the output of the previous stage.
return;
}
+ builder.update_submodule(&Path::new("library").join("stdarch"));
+
let mut target_deps = builder.ensure(StartupObjects { compiler, target });
let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
use crate::tool::{self, prepare_tool_cargo, SourceType, Tool};
use crate::util::symlink_dir;
+macro_rules! submodule_helper {
+ ($path:expr, submodule) => {
+ $path
+ };
+ ($path:expr, submodule = $submodule:literal) => {
+ $submodule
+ };
+}
+
macro_rules! book {
- ($($name:ident, $path:expr, $book_name:expr;)+) => {
+ ($($name:ident, $path:expr, $book_name:expr $(, submodule $(= $submodule:literal)? )? ;)+) => {
$(
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct $name {
}
fn run(self, builder: &Builder<'_>) {
+ $(
+ let path = Path::new(submodule_helper!( $path, submodule $( = $submodule )? ));
+ builder.update_submodule(&path);
+ )?
builder.ensure(RustbookSrc {
target: self.target,
name: INTERNER.intern_str($book_name),
// NOTE: When adding a book here, make sure to ALSO build the book by
// adding a build step in `src/bootstrap/builder.rs`!
+// NOTE: Make sure to add the corresponding submodule when adding a new book.
+// FIXME: Make checking for a submodule automatic somehow (maybe by having a list of all submodules
+// and checking against it?).
book!(
- CargoBook, "src/tools/cargo/src/doc", "cargo";
- EditionGuide, "src/doc/edition-guide", "edition-guide";
- EmbeddedBook, "src/doc/embedded-book", "embedded-book";
- Nomicon, "src/doc/nomicon", "nomicon";
- Reference, "src/doc/reference", "reference";
- RustByExample, "src/doc/rust-by-example", "rust-by-example";
+ CargoBook, "src/tools/cargo/src/doc", "cargo", submodule = "src/tools/cargo";
+ EditionGuide, "src/doc/edition-guide", "edition-guide", submodule;
+ EmbeddedBook, "src/doc/embedded-book", "embedded-book", submodule;
+ Nomicon, "src/doc/nomicon", "nomicon", submodule;
+ Reference, "src/doc/reference", "reference", submodule;
+ RustByExample, "src/doc/rust-by-example", "rust-by-example", submodule;
RustdocBook, "src/doc/rustdoc", "rustdoc";
);
/// * Index page
/// * Redirect pages
fn run(self, builder: &Builder<'_>) {
+ let relative_path = Path::new("src").join("doc").join("book");
+ builder.update_submodule(&relative_path);
+
let compiler = self.compiler;
let target = self.target;
builder.ensure(RustbookSrc {
target,
name: INTERNER.intern_str("book"),
- src: INTERNER.intern_path(builder.src.join("src/doc/book")),
+ src: INTERNER.intern_path(builder.src.join(&relative_path)),
});
// building older edition redirects
builder.ensure(RustbookSrc {
target,
name: INTERNER.intern_string(format!("book/{}", edition)),
- src: INTERNER.intern_path(builder.src.join("src/doc/book").join(edition)),
+ src: INTERNER.intern_path(builder.src.join(&relative_path).join(edition)),
});
}
// build the redirect pages
builder.info(&format!("Documenting book redirect pages ({})", target));
- for file in t!(fs::read_dir(builder.src.join("src/doc/book/redirects"))) {
+ for file in t!(fs::read_dir(builder.src.join(&relative_path).join("redirects"))) {
let file = t!(file);
let path = file.path();
let path = path.to_str().unwrap();
slice::from_ref(&self.build.triple)
}
+ // modified from `check_submodule` and `update_submodule` in bootstrap.py
+ /// Given a path to the directory of a submodule, update it.
+ ///
+ /// `relative_path` should be relative to the root of the git repository, not an absolute path.
+ pub(crate) fn update_submodule(&self, relative_path: &Path) {
+ fn dir_is_empty(dir: &Path) -> bool {
+ t!(std::fs::read_dir(dir)).next().is_none()
+ }
+
+ if !self.config.submodules {
+ return;
+ }
+
+ let absolute_path = self.config.src.join(relative_path);
+
+ // NOTE: The check for the empty directory is here because when running x.py the first time,
+ // the submodule won't be checked out. Check it out now so we can build it.
+ if !channel::GitInfo::new(false, relative_path).is_git() && !dir_is_empty(&absolute_path) {
+ return;
+ }
+
+ // check_submodule
+ if self.config.fast_submodules {
+ let checked_out_hash = output(
+ Command::new("git").args(&["rev-parse", "HEAD"]).current_dir(&absolute_path),
+ );
+ // update_submodules
+ let recorded = output(
+ Command::new("git")
+ .args(&["ls-tree", "HEAD"])
+ .arg(relative_path)
+ .current_dir(&self.config.src),
+ );
+ let actual_hash = recorded
+ .split_whitespace()
+ .nth(2)
+ .unwrap_or_else(|| panic!("unexpected output `{}`", recorded));
+
+ // update_submodule
+ if actual_hash == checked_out_hash.trim_end() {
+ // already checked out
+ return;
+ }
+ }
+
+ println!("Updating submodule {}", relative_path.display());
+ self.run(
+ Command::new("git")
+ .args(&["submodule", "-q", "sync"])
+ .arg(relative_path)
+ .current_dir(&self.config.src),
+ );
+
+ // Try passing `--progress` to start, then run git again without if that fails.
+ let update = |progress: bool| {
+ let mut git = Command::new("git");
+ git.args(&["submodule", "update", "--init", "--recursive"]);
+ if progress {
+ git.arg("--progress");
+ }
+ git.arg(relative_path).current_dir(&self.config.src);
+ git
+ };
+ // NOTE: doesn't use `try_run` because this shouldn't print an error if it fails.
+ if !update(true).status().map_or(false, |status| status.success()) {
+ self.run(&mut update(false));
+ }
+
+ self.run(Command::new("git").args(&["reset", "-q", "--hard"]).current_dir(&absolute_path));
+ self.run(Command::new("git").args(&["clean", "-qdfx"]).current_dir(absolute_path));
+ }
+
+ /// If any submodule has been initialized already, sync it unconditionally.
+ /// This avoids contributors checking in a submodule change by accident.
+ pub fn maybe_update_submodules(&self) {
+ // WARNING: keep this in sync with the submodules hard-coded in bootstrap.py
+ const BOOTSTRAP_SUBMODULES: &[&str] = &[
+ "src/tools/rust-installer",
+ "src/tools/cargo",
+ "src/tools/rls",
+ "src/tools/miri",
+ "library/backtrace",
+ "library/stdarch",
+ ];
+ // Avoid running git when there isn't a git checkout.
+ if !self.config.submodules {
+ return;
+ }
+ let output = output(
+ Command::new("git")
+ .args(&["config", "--file"])
+ .arg(&self.config.src.join(".gitmodules"))
+ .args(&["--get-regexp", "path"]),
+ );
+ for line in output.lines() {
+ // Look for `submodule.$name.path = $path`
+ // Sample output: `submodule.src/rust-installer.path src/tools/rust-installer`
+ let submodule = Path::new(line.splitn(2, ' ').nth(1).unwrap());
+ // avoid updating submodules twice
+ if !BOOTSTRAP_SUBMODULES.iter().any(|&p| Path::new(p) == submodule)
+ && channel::GitInfo::new(false, submodule).is_git()
+ {
+ self.update_submodule(submodule);
+ }
+ }
+ }
+
/// Executes the entire build, as configured by the flags and configuration.
pub fn build(&mut self) {
unsafe {
job::setup(self);
}
- // If the LLVM submodule has been initialized already, sync it unconditionally. This avoids
- // contributors checking in a submodule change by accident.
- if self.in_tree_llvm_info.is_git() {
- native::update_llvm_submodule(self);
- }
+ self.maybe_update_submodules();
if let Subcommand::Format { check, paths } = &self.config.cmd {
return format::format(self, *check, &paths);
use crate::builder::{Builder, RunConfig, ShouldRun, Step};
use crate::config::TargetSelection;
use crate::util::{self, exe};
-use crate::{Build, GitRepo};
+use crate::GitRepo;
use build_helper::up_to_date;
pub struct Meta {
Err(Meta { stamp, build_llvm_config, out_dir, root: root.into() })
}
-// modified from `check_submodule` and `update_submodule` in bootstrap.py
-pub(crate) fn update_llvm_submodule(build: &Build) {
- let llvm_project = &Path::new("src").join("llvm-project");
-
- fn dir_is_empty(dir: &Path) -> bool {
- t!(std::fs::read_dir(dir)).next().is_none()
- }
-
- if !build.config.submodules {
- return;
- }
-
- // NOTE: The check for the empty directory is here because when running x.py
- // the first time, the llvm submodule won't be checked out. Check it out
- // now so we can build it.
- if !build.in_tree_llvm_info.is_git() && !dir_is_empty(&build.config.src.join(llvm_project)) {
- return;
- }
-
- // check_submodule
- if build.config.fast_submodules {
- let checked_out_hash = output(
- Command::new("git")
- .args(&["rev-parse", "HEAD"])
- .current_dir(build.config.src.join(llvm_project)),
- );
- // update_submodules
- let recorded = output(
- Command::new("git")
- .args(&["ls-tree", "HEAD"])
- .arg(llvm_project)
- .current_dir(&build.config.src),
- );
- let actual_hash = recorded
- .split_whitespace()
- .nth(2)
- .unwrap_or_else(|| panic!("unexpected output `{}`", recorded));
-
- // update_submodule
- if actual_hash == checked_out_hash.trim_end() {
- // already checked out
- return;
- }
- }
-
- println!("Updating submodule {}", llvm_project.display());
- build.run(
- Command::new("git")
- .args(&["submodule", "-q", "sync"])
- .arg(llvm_project)
- .current_dir(&build.config.src),
- );
-
- // Try passing `--progress` to start, then run git again without if that fails.
- let update = |progress: bool| {
- let mut git = Command::new("git");
- git.args(&["submodule", "update", "--init", "--recursive"]);
- if progress {
- git.arg("--progress");
- }
- git.arg(llvm_project).current_dir(&build.config.src);
- git
- };
- // NOTE: doesn't use `try_run` because this shouldn't print an error if it fails.
- if !update(true).status().map_or(false, |status| status.success()) {
- build.run(&mut update(false));
- }
-
- build.run(
- Command::new("git")
- .args(&["reset", "-q", "--hard"])
- .current_dir(build.config.src.join(llvm_project)),
- );
- build.run(
- Command::new("git")
- .args(&["clean", "-qdfx"])
- .current_dir(build.config.src.join(llvm_project)),
- );
-}
-
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub struct Llvm {
pub target: TargetSelection,
Err(m) => m,
};
- if !builder.config.dry_run {
- update_llvm_submodule(builder);
- }
+ builder.update_submodule(&Path::new("src").join("llvm-project"));
if builder.config.llvm_link_shared
&& (target.contains("windows") || target.contains("apple-darwin"))
{
// We remove existing folder to be sure there won't be artifacts remaining.
let _ = fs::remove_dir_all(&out_dir);
- let src_path = "src/test/rustdoc-gui/src";
+ let src_path = builder.build.src.join("src/test/rustdoc-gui/src");
// We generate docs for the libraries present in the rustdoc-gui's src folder.
- let mut cargo = Command::new(&builder.initial_cargo);
- cargo
- .arg("doc")
- .arg("--workspace")
- .arg("--target-dir")
- .arg(&out_dir)
- .env("RUSTDOC", builder.rustdoc(self.compiler))
- .env("RUSTC", builder.rustc(self.compiler))
- .current_dir(&builder.build.src.join(src_path));
- builder.run(&mut cargo);
+ for entry in src_path.read_dir().expect("read_dir call failed") {
+ if let Ok(entry) = entry {
+ let path = entry.path();
+
+ if !path.is_dir() {
+ continue;
+ }
+
+ let mut cargo = Command::new(&builder.initial_cargo);
+ cargo
+ .arg("doc")
+ .arg("--target-dir")
+ .arg(&out_dir)
+ .env("RUSTDOC", builder.rustdoc(self.compiler))
+ .env("RUSTC", builder.rustc(self.compiler))
+ .current_dir(path);
+ builder.run(&mut cargo);
+ }
+ }
// We now run GUI tests.
let mut command = Command::new(&nodejs);
}
fn run(self, builder: &Builder<'_>) {
- let src = builder.src.join("src/doc/rustc-dev-guide");
+ let relative_path = Path::new("src").join("doc").join("rustc-dev-guide");
+ builder.update_submodule(&relative_path);
+
+ let src = builder.src.join(relative_path);
let mut rustbook_cmd = builder.tool_cmd(Tool::Rustbook);
let toolstate = if try_run(builder, rustbook_cmd.arg("linkcheck").arg(&src)) {
ToolState::TestPass
use std::collections::HashSet;
use std::env;
use std::fs;
-use std::path::PathBuf;
+use std::path::{Path, PathBuf};
use std::process::{exit, Command};
use build_helper::t;
$path:expr,
$tool_name:expr,
stable = $stable:expr,
- $(in_tree = $in_tree:expr,)*
+ $(in_tree = $in_tree:expr,)?
+ $(submodule = $submodule:literal,)?
$extra_deps:block;)+) => {
$(
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
#[allow(unused_mut)]
fn run(mut $sel, $builder: &Builder<'_>) -> Option<PathBuf> {
$extra_deps
+ $( $builder.update_submodule(&Path::new("src").join("tools").join($submodule)); )?
$builder.ensure(ToolBuild {
compiler: $sel.compiler,
target: $sel.target,
// Note: tools need to be also added to `Builder::get_step_descriptions` in `builder.rs`
// to make `./x.py build <tool>` work.
+// Note: Most submodule updates for tools are handled by bootstrap.py, since they're needed just to
+// invoke Cargo to build bootstrap. See the comment there for more details.
tool_extended!((self, builder),
Cargofmt, rustfmt, "src/tools/rustfmt", "cargo-fmt", stable=true, in_tree=true, {};
CargoClippy, clippy, "src/tools/clippy", "cargo-clippy", stable=true, in_tree=true, {};
};
RustDemangler, rust_demangler, "src/tools/rust-demangler", "rust-demangler", stable=false, in_tree=true, {};
Rustfmt, rustfmt, "src/tools/rustfmt", "rustfmt", stable=true, in_tree=true, {};
- RustAnalyzer, rust_analyzer, "src/tools/rust-analyzer/crates/rust-analyzer", "rust-analyzer", stable=false, {};
+ RustAnalyzer, rust_analyzer, "src/tools/rust-analyzer/crates/rust-analyzer", "rust-analyzer", stable=false, submodule="rust-analyzer", {};
);
impl<'a> Builder<'a> {
-Subproject commit a90f07f1e9a7fc75dc9105a6c6f16d5c13edceb0
+Subproject commit eac55314210519238652f12b30fec9daea61f7fe
-Subproject commit 5d57b3832f8d308a9f478ce0a69799548f27ad4d
+Subproject commit af696ce8ea526445590ae0ca66a8128d2a95a69a
-Subproject commit 506840eb73b0749336e1d5274e16d6393892ee82
+Subproject commit 09986cd352404eb4659db44613b27cac9aa652fc
-Subproject commit ab60513a3a5a0591e237fddff5d027a982648392
+Subproject commit 82d75cf423e4a7824fb36e73ccb18519d6900610
-Subproject commit 028f93a61500fe8f746ee7cc6b204ea6c9f42935
+Subproject commit 1db6bb483cc87ad3b424d9aba764fe622960a1be
-Subproject commit 60e282559104035985331645907c3d9f842312c5
+Subproject commit 93422c21baca585dc88357ec886a48f6ddc7d665
--- /dev/null
+# `force-warn`
+
+The tracking issue for this feature is: [#85512](https://github.com/rust-lang/rust/issues/85512).
+
+------------------------
+
+This feature allows you to cause any lint to produce a warning even if the lint has a different level by default or another level is set somewhere else. For instance, the `force-warn` option can be used to make a lint (e.g., `dead_code`) produce a warning even if that lint is allowed in code with `#![allow(dead_code)]`.
+
+## Example
+
+```rust,ignore (partial-example)
+#![allow(dead_code)]
+
+fn dead_function() {}
+// This would normally not produce a warning even though the
+// function is not used, because dead code is being allowed
+
+fn main() {}
+```
+
+We can force a warning to be produced by providing `--force-warn dead_code` to rustc.
+++ /dev/null
-# `force-warns`
-
-The tracking issue for this feature is: [#85512](https://github.com/rust-lang/rust/issues/85512).
-
-------------------------
-
-This feature allows you to cause any lint to produce a warning even if the lint has a different level by default or another level is set somewhere else. For instance, the `force-warns` option can be used to make a lint (e.g., `dead_code`) produce a warning even if that lint is allowed in code with `#![allow(dead_code)]`.
-
-## Example
-
-```rust,ignore (partial-example)
-#![allow(dead_code)]
-
-fn dead_function() {}
-// This would normally not produce a warning even though the
-// function is not used, because dead code is being allowed
-
-fn main() {}
-```
-
-We can force a warning to be produced by providing `--force-warns dead_code` to rustc.
+++ /dev/null
-# `impl_trait_in_bindings`
-
-The tracking issue for this feature is: [#63065]
-
-[#63065]: https://github.com/rust-lang/rust/issues/63065
-
-------------------------
-
-The `impl_trait_in_bindings` feature gate lets you use `impl Trait` syntax in
-`let`, `static`, and `const` bindings.
-
-A simple example is:
-
-```rust
-#![feature(impl_trait_in_bindings)]
-
-use std::fmt::Debug;
-
-fn main() {
- let a: impl Debug + Clone = 42;
- let b = a.clone();
- println!("{:?}", b); // prints `42`
-}
-```
-
-Note however that because the types of `a` and `b` are opaque in the above
-example, calling inherent methods or methods outside of the specified traits
-(e.g., `a.abs()` or `b.abs()`) is not allowed, and yields an error.
})
.collect(),
];
- let default_settings = default_settings.into_iter().flatten().collect();
+ let default_settings = default_settings
+ .into_iter()
+ .flatten()
+ .map(
+ // The keys here become part of `data-` attribute names in the generated HTML. The
+ // browser does a strange mapping when converting them into attributes on the
+ // `dataset` property on the DOM HTML Node:
+ // https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset
+ //
+ // The original key values we have are the same as the DOM storage API keys and the
+ // command line options, so contain `-`. Our Javascript needs to be able to look
+ // these values up both in `dataset` and in the storage API, so it needs to be able
+ // to convert the names back and forth. Despite doing this kebab-case to
+ // StudlyCaps transformation automatically, the JS DOM API does not provide a
+ // mechanism for doing the just transformation on a string. So we want to avoid
+ // the StudlyCaps representation in the `dataset` property.
+ //
+ // We solve this by replacing all the `-`s with `_`s. We do that here, when we
+ // generate the `data-` attributes, and in the JS, when we look them up. (See
+ // `getSettingValue` in `storage.js.`) Converting `-` to `_` is simple in JS.
+ //
+ // The values will be HTML-escaped by the default Tera escaping.
+ |(k, v)| (k.replace('-', "_"), v),
+ )
+ .collect();
let test_args = matches.opt_strs("test-args");
let test_args: Vec<String> =
let show_type_layout = matches.opt_present("show-type-layout");
let nocapture = matches.opt_present("nocapture");
- let (lint_opts, describe_lints, lint_cap, _) =
+ let (lint_opts, describe_lints, lint_cap) =
get_cmd_lint_options(matches, error_format, &debugging_opts);
Ok(Options {
/// A subset of [`opts()`] used for rendering summaries.
pub(crate) fn summary_opts() -> Options {
- Options::ENABLE_STRIKETHROUGH | Options::ENABLE_SMART_PUNCTUATION
+ Options::ENABLE_STRIKETHROUGH | Options::ENABLE_SMART_PUNCTUATION | Options::ENABLE_TABLES
}
/// When `to_string` is called, this struct will emit the HTML corresponding to
)
}
+fn is_forbidden_tag(t: &Tag<'_>) -> bool {
+ matches!(t, Tag::CodeBlock(_) | Tag::Table(_) | Tag::TableHead | Tag::TableRow | Tag::TableCell)
+}
+
impl<'a, I: Iterator<Item = Event<'a>>> Iterator for SummaryLine<'a, I> {
type Item = Event<'a>;
if let Some(event) = self.inner.next() {
let mut is_start = true;
let is_allowed_tag = match event {
- Event::Start(Tag::CodeBlock(_)) | Event::End(Tag::CodeBlock(_)) => {
- return None;
- }
Event::Start(ref c) => {
+ if is_forbidden_tag(c) {
+ return None;
+ }
self.depth += 1;
check_if_allowed_tag(c)
}
Event::End(ref c) => {
+ if is_forbidden_tag(c) {
+ return None;
+ }
self.depth -= 1;
is_start = false;
check_if_allowed_tag(c)
use clean::AttributesExt;
use std::cmp::Ordering;
+use std::fmt;
use rustc_data_structures::fx::FxHashMap;
use rustc_hir as hir;
n_fields > 12
}
-fn toggle_open(w: &mut Buffer, text: &str) {
+fn toggle_open(w: &mut Buffer, text: impl fmt::Display) {
write!(
w,
"<details class=\"rustdoc-toggle type-contents-toggle\">\
let consts = t.items.iter().filter(|m| m.is_associated_const()).collect::<Vec<_>>();
let required = t.items.iter().filter(|m| m.is_ty_method()).collect::<Vec<_>>();
let provided = t.items.iter().filter(|m| m.is_method()).collect::<Vec<_>>();
+ let count_types = types.len();
+ let count_consts = consts.len();
+ let count_methods = required.len() + provided.len();
// Output the trait definition
wrap_into_docblock(w, |w| {
let mut toggle = false;
// If there are too many associated types, hide _everything_
- if should_hide_fields(types.len()) {
+ if should_hide_fields(count_types) {
toggle = true;
- toggle_open(w, "associated items");
+ toggle_open(
+ w,
+ format_args!("{} associated items", count_types + count_consts + count_methods),
+ );
}
for t in &types {
render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait, cx);
// We also do this if the types + consts is large because otherwise we could
// render a bunch of types and _then_ a bunch of consts just because both were
// _just_ under the limit
- if !toggle && should_hide_fields(types.len() + consts.len()) {
+ if !toggle && should_hide_fields(count_types + count_consts) {
toggle = true;
- toggle_open(w, "associated constants and methods");
+ toggle_open(
+ w,
+ format_args!(
+ "{} associated constant{} and {} method{}",
+ count_consts,
+ pluralize(count_consts),
+ count_methods,
+ pluralize(count_methods),
+ ),
+ );
}
if !types.is_empty() && !consts.is_empty() {
w.write_str("\n");
render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait, cx);
w.write_str(";\n");
}
- if !toggle && should_hide_fields(required.len() + provided.len()) {
+ if !toggle && should_hide_fields(count_methods) {
toggle = true;
- toggle_open(w, "methods");
+ toggle_open(w, format_args!("{} methods", count_methods));
}
if !consts.is_empty() && !required.is_empty() {
w.write_str("\n");
w.write_str(" {}");
} else {
w.write_str(" {\n");
- let toggle = should_hide_fields(e.variants.len());
+ let count_variants = e.variants.len();
+ let toggle = should_hide_fields(count_variants);
if toggle {
- toggle_open(w, "variants");
+ toggle_open(w, format_args!("{} variants", count_variants));
}
for v in &e.variants {
w.write_str(" ");
use crate::clean::Variant;
if let clean::VariantItem(Variant::Struct(ref s)) = *variant.kind {
- toggle_open(w, "fields");
+ let count_fields = s.fields.len();
+ toggle_open(w, format_args!("{} field{}", count_fields, pluralize(count_fields)));
let variant_id = cx.derive_id(format!(
"{}.{}.fields",
ItemType::Variant,
fields.iter().filter(|f| matches!(*f.kind, clean::StructFieldItem(..))).count();
let toggle = should_hide_fields(count_fields);
if toggle {
- toggle_open(w, "fields");
+ toggle_open(w, format_args!("{} fields", count_fields));
}
for field in fields {
let has_visible_fields = count_fields > 0;
let toggle = should_hide_fields(count_fields);
if toggle {
- toggle_open(w, "fields");
+ toggle_open(w, format_args!("{} fields", count_fields));
}
for field in fields {
if let clean::StructFieldItem(ref ty) = *field.kind {
writeln!(w, "</div>");
}
+
+fn pluralize(count: usize) -> &'static str {
+ if count > 1 { "s" } else { "" }
+}
.docblock table {
margin: .5em 0;
width: calc(100% - 2px);
- border: 1px dashed;
+ overflow-x: auto;
+ display: block;
}
.docblock table td {
border-bottom-color: #5c6773;
}
-.docblock table, .docblock table td, .docblock table th {
+.docblock table td, .docblock table th {
border-color: #5c6773;
}
border-bottom-color: #DDD;
}
-.docblock table, .docblock table td, .docblock table th {
+.docblock table td, .docblock table th {
border-color: #ddd;
}
border-bottom-color: #ddd;
}
-.docblock table, .docblock table td, .docblock table th {
+.docblock table td, .docblock table th {
border-color: #ddd;
}
return current;
}
if (settingsDataset !== null) {
+ // See the comment for `default_settings.into_iter()` etc. in
+ // `Options::from_matches` in `librustdoc/config.rs`.
var def = settingsDataset[settingName.replace(/-/g,'_')];
if (def !== undefined) {
return def;
"LEVEL",
)
}),
- unstable("force-warns", |o| {
+ unstable("force-warn", |o| {
o.optopt(
"",
- "force-warns",
+ "force-warn",
"Lints that will warn even if allowed somewhere else",
"LINTS",
)
// cdb-command:x a!function_names::*::impl_function*
// cdb-check:[...] a!function_names::Mod1::TestStruct2::impl_function (void)
// cdb-check:[...] a!function_names::TestStruct1::impl_function (void)
-// cdb-check:[...] a!function_names::GenericStruct<i32, i32>::impl_function<i32, i32> (void)
+// cdb-check:[...] a!function_names::GenericStruct<i32,i32>::impl_function<i32,i32> (void)
// Trait implementations
// cdb-command:x a!function_names::*::trait_function*
// cdb-check:[...] a!function_names::impl$3::trait_function<i32> (void)
+// cdb-check:[...] a!function_names::impl$6::trait_function<i32,1> (void)
// cdb-check:[...] a!function_names::impl$1::trait_function (void)
-// cdb-check:[...] a!function_names::impl$6::trait_function<i32, 1> (void)
// cdb-check:[...] a!function_names::impl$5::trait_function3<function_names::TestStruct1> (void)
// cdb-check:[...] a!function_names::Mod1::impl$1::trait_function (void)
// Closure
// cdb-command:x a!function_names::*::closure*
+// cdb-check:[...] a!function_names::impl$2::impl_function::closure$0<i32,i32> (void)
// cdb-check:[...] a!function_names::main::closure$0 (void)
// cdb-check:[...] a!function_names::generic_func::closure$0<i32> (void)
-// cdb-check:[...] a!function_names::impl$2::impl_function::closure$0<i32, i32> (void)
// Generator
// cdb-command:x a!function_names::*::generator*
// cdb-command:g
// cdb-command:dx int_int
-// cdb-check:int_int [Type: generic_struct::AGenericStruct<i32, i32>]
+// cdb-check:int_int [Type: generic_struct::AGenericStruct<i32,i32>]
// cdb-check:[...]key : 0 [Type: int]
// cdb-check:[...]value : 1 [Type: int]
// cdb-command:dx int_float
-// cdb-check:int_float [Type: generic_struct::AGenericStruct<i32, f64>]
+// cdb-check:int_float [Type: generic_struct::AGenericStruct<i32,f64>]
// cdb-check:[...]key : 2 [Type: int]
// cdb-check:[...]value : 3.500000 [Type: double]
// cdb-command:dx float_int
-// cdb-check:float_int [Type: generic_struct::AGenericStruct<f64, i32>]
+// cdb-check:float_int [Type: generic_struct::AGenericStruct<f64,i32>]
// cdb-check:[...]key : 4.500000 [Type: double]
// cdb-check:[...]value : 5 [Type: int]
// cdb-command:dx float_int_float
-// cdb-check:float_int_float [Type: generic_struct::AGenericStruct<f64, generic_struct::AGenericStruct<i32, f64> >]
+// cdb-check:float_int_float [Type: generic_struct::AGenericStruct<f64,generic_struct::AGenericStruct<i32,f64> >]
// cdb-check:[...]key : 6.500000 [Type: double]
-// cdb-check:[...]value [Type: generic_struct::AGenericStruct<i32, f64>]
+// cdb-check:[...]value [Type: generic_struct::AGenericStruct<i32,f64>]
#![feature(omit_gdb_pretty_printer_section)]
// cdb-check: [+0x000] discriminant : 0x[...] [Type: enum$<core::option::Option<alloc::string::String>, 1, [...], Some>::Discriminant$]
// cdb-command: dx -r2 l,!
-// cdb-check:l,! : $T2 [Type: enum$<core::result::Result<u32, enum$<msvc_pretty_enums::Empty> >, Ok>]
-// cdb-check: [+0x000] Ok [Type: enum$<core::result::Result<u32, enum$<msvc_pretty_enums::Empty> >, Ok>::Ok]
+// cdb-check:l,! : $T2 [Type: enum$<core::result::Result<u32,enum$<msvc_pretty_enums::Empty> >, Ok>]
+// cdb-check: [+0x000] Ok [Type: enum$<core::result::Result<u32,enum$<msvc_pretty_enums::Empty> >, Ok>::Ok]
// cdb-check: [+0x000] __0 : 0x2a [Type: unsigned int]
pub enum CStyleEnum {
// cdb-command: g
// cdb-command: dx hash_set,d
-// cdb-check:hash_set,d [...] : { len=15 } [Type: [...]::HashSet<u64, [...]>]
+// cdb-check:hash_set,d [...] : { len=15 } [Type: [...]::HashSet<u64,[...]>]
// cdb-check: [len] : 15 [Type: [...]]
// cdb-check: [capacity] : [...]
// cdb-check: [[...]] [...] : 0 [Type: u64]
// cdb-check: [[...]] [...] : 14 [Type: u64]
// cdb-command: dx hash_map,d
-// cdb-check:hash_map,d [...] : { len=15 } [Type: [...]::HashMap<u64, u64, [...]>]
+// cdb-check:hash_map,d [...] : { len=15 } [Type: [...]::HashMap<u64,u64,[...]>]
// cdb-check: [len] : 15 [Type: [...]]
// cdb-check: [capacity] : [...]
// cdb-check: ["0x0"] : 0 [Type: unsigned __int64]
// cdb-check: [3] : 3 [Type: int]
// cdb-command: dx vec,d
-// cdb-check:vec,d [...] : { len=4 } [Type: [...]::Vec<u64, alloc::alloc::Global>]
+// cdb-check:vec,d [...] : { len=4 } [Type: [...]::Vec<u64,alloc::alloc::Global>]
// cdb-check: [len] : 4 [Type: [...]]
// cdb-check: [capacity] : [...] [Type: [...]]
// cdb-check: [0] : 4 [Type: unsigned __int64]
// cdb-command: g
// cdb-command: dx x,d
-// cdb-check:x,d : Ok [Type: enum$<core::result::Result<i32, str> >]
+// cdb-check:x,d : Ok [Type: enum$<core::result::Result<i32,str> >]
// cdb-check: [...] __0 : -3 [Type: int]
// cdb-command: dx y
-// cdb-check:y : Err [Type: enum$<core::result::Result<i32, str> >]
+// cdb-check:y : Err [Type: enum$<core::result::Result<i32,str> >]
// cdb-check: [...] __0 : "Some error message" [Type: str]
fn main()
// gdb-check:type = &mut dyn type_names::Trait2<type_names::mod1::mod2::Struct3, type_names::GenericStruct<usize, isize>>
// gdb-command:whatis no_principal_trait
-// gdb-check:type = alloc::boxed::Box<dyn core::marker::Send + core::marker::Sync, alloc::alloc::Global>
+// gdb-check:type = alloc::boxed::Box<(dyn core::marker::Send + core::marker::Sync), alloc::alloc::Global>
+
+// gdb-command:whatis has_associated_type_trait
+// gdb-check:type = &(dyn type_names::Trait3<u32, AssocType=isize> + core::marker::Send)
+
// BARE FUNCTIONS
// gdb-command:whatis rust_fn
// 0-sized structs appear to be optimized away in some cases, so only check the structs that do
// actually appear.
// cdb-command:dv /t *_struct
-// cdb-check:struct type_names::GenericStruct<enum$<type_names::mod1::Enum2>, f64> mut_generic_struct = [...]
+// cdb-check:struct type_names::GenericStruct<enum$<type_names::mod1::Enum2>,f64> mut_generic_struct = [...]
// ENUMS
// cdb-command:dv /t *_enum_*
// BOX
// cdb-command:dv /t box*
-// cdb-check:struct tuple$<alloc::boxed::Box<f32, alloc::alloc::Global>,i32> box1 = [...]
-// cdb-check:struct tuple$<alloc::boxed::Box<enum$<type_names::mod1::mod2::Enum3<f32> >, alloc::alloc::Global>,i32> box2 = [...]
+// cdb-check:struct tuple$<alloc::boxed::Box<f32,alloc::alloc::Global>,i32> box1 = [...]
+// cdb-check:struct tuple$<alloc::boxed::Box<enum$<type_names::mod1::mod2::Enum3<f32> >,alloc::alloc::Global>,i32> box2 = [...]
// REFERENCES
// cdb-command:dv /t *ref*
// cdb-check:struct tuple$<ref$<type_names::Struct1>,i32> ref1 = [...]
-// cdb-check:struct tuple$<ref$<type_names::GenericStruct<char, type_names::Struct1> >,i32> ref2 = [...]
+// cdb-check:struct tuple$<ref$<type_names::GenericStruct<char,type_names::Struct1> >,i32> ref2 = [...]
// cdb-check:struct tuple$<ref_mut$<type_names::Struct1>,i32> mut_ref1 = [...]
-// cdb-check:struct tuple$<ref_mut$<type_names::GenericStruct<enum$<type_names::mod1::Enum2>, f64> >,i32> mut_ref2 = [...]
+// cdb-check:struct tuple$<ref_mut$<type_names::GenericStruct<enum$<type_names::mod1::Enum2>,f64> >,i32> mut_ref2 = [...]
// RAW POINTERS
// cdb-command:dv /t *_ptr*
// cdb-command:dv /t *vec*
// cdb-check:struct tuple$<array$<type_names::Struct1,3>,i16> fixed_size_vec1 = [...]
// cdb-check:struct tuple$<array$<usize,3>,i16> fixed_size_vec2 = [...]
-// cdb-check:struct alloc::vec::Vec<usize, alloc::alloc::Global> vec1 = [...]
-// cdb-check:struct alloc::vec::Vec<enum$<type_names::mod1::Enum2>, alloc::alloc::Global> vec2 = [...]
+// cdb-check:struct alloc::vec::Vec<usize,alloc::alloc::Global> vec1 = [...]
+// cdb-check:struct alloc::vec::Vec<enum$<type_names::mod1::Enum2>,alloc::alloc::Global> vec2 = [...]
// cdb-command:dv /t slice*
// cdb-check:struct slice$<usize> slice1 = [...]
// cdb-check:struct slice$<enum$<type_names::mod1::Enum2> > slice2 = [...]
// TRAITS
// cdb-command:dv /t *_trait
-// cdb-check:struct ref_mut$<dyn$<type_names::Trait2<type_names::mod1::mod2::Struct3, type_names::GenericStruct<usize, isize> > > > generic_mut_ref_trait = [...]
-// cdb-check:struct ref$<dyn$<type_names::Trait2<type_names::Struct1, type_names::Struct1> > > generic_ref_trait = [...]
-// cdb-check:struct alloc::boxed::Box<dyn$<type_names::Trait2<i32, type_names::mod1::Struct2> >, alloc::alloc::Global> generic_box_trait = [...]
-// cdb-check:struct alloc::boxed::Box<dyn$<type_names::Trait1>, alloc::alloc::Global> box_trait = [...]
+// cdb-check:struct ref_mut$<dyn$<type_names::Trait2<type_names::mod1::mod2::Struct3,type_names::GenericStruct<usize,isize> > > > generic_mut_ref_trait = [...]
+// cdb-check:struct ref$<dyn$<type_names::Trait2<type_names::Struct1,type_names::Struct1> > > generic_ref_trait = [...]
+// cdb-check:struct alloc::boxed::Box<dyn$<type_names::Trait2<i32,type_names::mod1::Struct2> >,alloc::alloc::Global> generic_box_trait = [...]
+// cdb-check:struct alloc::boxed::Box<dyn$<type_names::Trait1>,alloc::alloc::Global> box_trait = [...]
// cdb-check:struct ref$<dyn$<type_names::Trait1> > ref_trait = [...]
// cdb-check:struct ref_mut$<dyn$<type_names::Trait1> > mut_ref_trait = [...]
-// cdb-check:struct alloc::boxed::Box<dyn$<core::marker::Send, core::marker::Sync>, alloc::alloc::Global> no_principal_trait = [...]
-// cdb-check:struct ref$<dyn$<type_names::Trait3> > has_associated_type_trait = struct ref$<dyn$<type_names::Trait3> >
+// cdb-check:struct alloc::boxed::Box<dyn$<core::marker::Send,core::marker::Sync>,alloc::alloc::Global> no_principal_trait = [...]
+// cdb-check:struct ref$<dyn$<type_names::Trait3<u32,assoc$<AssocType,isize> >,core::marker::Send> > has_associated_type_trait = struct ref$<dyn$<type_names::Trait3<u32,assoc$<AssocType,isize> >,core::marker::Send> >
// BARE FUNCTIONS
// cdb-command:dv /t *_fn*
-// cdb-check:struct tuple$<type_names::mod1::Struct2 (*)(type_names::GenericStruct<u16, u8>),usize> unsafe_fn_with_return_value = [...]
+// cdb-check:struct tuple$<type_names::mod1::Struct2 (*)(type_names::GenericStruct<u16,u8>),usize> unsafe_fn_with_return_value = [...]
// cdb-check:struct tuple$<type_names::Struct1 (*)(),usize> extern_c_fn_with_return_value = [...]
// cdb-check:struct tuple$<usize (*)(f64),usize> rust_fn_with_return_value = [...]
-// cdb-check:struct tuple$<void (*)(enum$<core::result::Result<char, f64> >),usize> unsafe_fn = [...]
+// cdb-check:struct tuple$<void (*)(enum$<core::result::Result<char,f64> >),usize> unsafe_fn = [...]
// cdb-check:struct tuple$<void (*)(isize),usize> extern_c_fn = [...]
-// cdb-check:struct tuple$<void (*)(enum$<core::option::Option<isize> >, enum$<core::option::Option<ref$<type_names::mod1::Struct2> >, 1, [...], Some>),usize> rust_fn = [...]
+// cdb-check:struct tuple$<void (*)(enum$<core::option::Option<isize> >,enum$<core::option::Option<ref$<type_names::mod1::Struct2> >, 1, [...], Some>),usize> rust_fn = [...]
// cdb-command:dv /t *_function*
// cdb-check:struct tuple$<isize (*)(ptr_const$<u8>, ...),usize> variadic_function = [...]
// cdb-check:struct tuple$<type_names::mod1::mod2::Struct3 (*)(type_names::mod1::mod2::Struct3),usize> generic_function_struct3 = [...]
trait Trait2<T1, T2> {
fn dummy(&self, _: T1, _: T2) {}
}
-trait Trait3 {
+trait Trait3<T> {
type AssocType;
- fn dummy(&self) {}
+ fn dummy(&self) -> T { panic!() }
}
impl Trait1 for isize {}
impl<T1, T2> Trait2<T1, T2> for isize {}
-impl Trait3 for isize {
+impl<T> Trait3<T> for isize {
type AssocType = isize;
}
let ref_trait = &0_isize as &dyn Trait1;
let mut mut_int1 = 0_isize;
let mut_ref_trait = (&mut mut_int1) as &mut dyn Trait1;
- let no_principal_trait = (box 0_isize) as Box<dyn Send + Sync>;
- let has_associated_type_trait = &0_isize as &dyn Trait3<AssocType = isize>;
+ let no_principal_trait = (box 0_isize) as Box<(dyn Send + Sync)>;
+ let has_associated_type_trait = &0_isize as &(dyn Trait3<u32, AssocType = isize> + Send);
let generic_box_trait = (box 0_isize) as Box<dyn Trait2<i32, mod1::Struct2>>;
let generic_ref_trait = (&0_isize) as &dyn Trait2<Struct1, Struct1>;
all:
$(RUSTDOC) --output-format=json x.html 2>&1 | diff - output-format-json.stderr
- $(RUSTC) --force-warns dead_code x.rs 2>&1 | diff - force-warns.stderr
+ $(RUSTC) --force-warn dead_code x.rs 2>&1 | diff - force-warn.stderr
--- /dev/null
+error: the `-Z unstable-options` flag must also be passed to enable the flag `--force-warn=lints`
+
+++ /dev/null
-error: the `-Z unstable-options` flag must also be passed to enable the flag `--force-warns=lints`
-
--- /dev/null
+// This test ensures that the default settings are correctly applied.
+//
+// The "settings" crate uses "ayu" as default setting, which is what we will
+// check.
+goto: file://|DOC_PATH|/settings/index.html
+// Wait a bit to be sure the default theme is applied.
+wait-for: 1000
+assert-css: ("body", {"background-color": "rgb(15, 20, 25)"})
--- /dev/null
+// This test ensures that the type declaration content overflow is handled inside the <pre> directly.
+goto: file://|DOC_PATH|/lib2/long_table/struct.Foo.html
+// We set a fixed size so there is no chance of "random" resize.
+size: (1100, 800)
+// Logically, the ".docblock" and the "<p>" should have the same scroll width.
+compare-elements-property: (".top-doc .docblock", ".top-doc .docblock > p", ["scrollWidth"])
+assert-property: (".top-doc .docblock", {"scrollWidth": "816"})
+// However, since there is overflow in the <table>, its scroll width is bigger.
+assert-property: (".top-doc .docblock table", {"scrollWidth": "1573"})
--- /dev/null
+// This test ensures that <table> elements aren't display in items summary.
+goto: file://|DOC_PATH|/lib2/summary_table/index.html
+// We check that we picked the right item first.
+assert-text: (".item-table .item-left", "Foo")
+// Then we check that its summary is empty.
+assert-text: (".item-table .item-right", "")
+++ /dev/null
-# This file is automatically @generated by Cargo.
-# It is not intended for manual editing.
-version = 3
-
-[[package]]
-name = "implementors"
-version = "0.1.0"
-
-[[package]]
-name = "lib2"
-version = "0.1.0"
-dependencies = [
- "implementors",
-]
-
-[[package]]
-name = "test_docs"
-version = "0.1.0"
+++ /dev/null
-[workspace]
-members = [
- "test_docs",
- "lib2",
- "implementors",
-]
+++ /dev/null
-[package]
-name = "implementors"
-version = "0.1.0"
-edition = "2018"
-
-[lib]
-path = "lib.rs"
+++ /dev/null
-pub trait Whatever {
- fn method() {}
-}
-
-pub struct Struct;
-
-impl Whatever for Struct {}
--- /dev/null
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "implementors"
+version = "0.1.0"
+
+[[package]]
+name = "lib2"
+version = "0.1.0"
+dependencies = [
+ "implementors",
+]
path = "lib.rs"
[dependencies]
-implementors = { path = "../implementors" }
+implementors = { path = "./implementors" }
--- /dev/null
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "implementors"
+version = "0.1.0"
--- /dev/null
+[package]
+name = "implementors"
+version = "0.1.0"
+edition = "2018"
+
+[lib]
+path = "lib.rs"
--- /dev/null
+pub trait Whatever {
+ fn method() {}
+}
+
+pub struct Struct;
+
+impl Whatever for Struct {}
pub trait ALongNameBecauseItHelpsTestingTheCurrentProblem: DerefMut<Target = u32>
+ From<u128> + Send + Sync + AsRef<str> + 'static {}
}
+
+pub mod long_table {
+ /// | This::is::a::kinda::very::long::header::number::one | This::is::a::kinda::very::long::header::number::two | This::is::a::kinda::very::long::header::number::one | This::is::a::kinda::very::long::header::number::two |
+ /// | ----------- | ----------- | ----------- | ----------- |
+ /// | This::is::a::kinda::long::content::number::one | This::is::a::kinda::very::long::content::number::two | This::is::a::kinda::long::content::number::one | This::is::a::kinda::very::long::content::number::two |
+ ///
+ /// I wanna sqdkfnqds f dsqf qds f dsqf dsq f dsq f qds f qds f qds f dsqq f dsf sqdf dsq fds f dsq f dq f ds fq sd fqds f dsq f sqd fsq df sd fdsqfqsd fdsq f dsq f dsqfd s dfq
+ pub struct Foo;
+}
+
+pub mod summary_table {
+ /// | header 1 | header 2 |
+ /// | -------- | -------- |
+ /// | content | content |
+ pub struct Foo;
+}
+++ /dev/null
-#[cfg(test)]
-mod tests {
- #[test]
- fn it_works() {
- assert_eq!(2 + 2, 4);
- }
-}
--- /dev/null
+[build]
+rustdocflags = ["--default-theme", "ayu"]
--- /dev/null
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "settings"
+version = "0.1.0"
--- /dev/null
+[package]
+name = "settings"
+version = "0.1.0"
+edition = "2018"
+
+[lib]
+path = "lib.rs"
--- /dev/null
+pub fn foo() {}
--- /dev/null
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "test_docs"
+version = "0.1.0"
--> $DIR/unknown-renamed-lints.rs:7:9
|
LL | #![deny(rustdoc::x)]
- | ^^^^^^^^^^
+ | ^^^^^^^^^^ help: did you mean: `rustdoc::all`
error: lint `intra_doc_link_resolution_failure` has been renamed to `rustdoc::broken_intra_doc_links`
--> $DIR/unknown-renamed-lints.rs:9:9
--- /dev/null
+// compile-flags: --default-theme ayu
+
+// @has default_theme/index.html
+// @has - '//script[@id="default-settings"]/@data-theme' 'ayu'
+// @has - '//script[@id="default-settings"]/@data-use_system_theme' 'false'
+
+pub fn whatever() {}
// @has 'toggle_item_contents/struct.BigPubStruct.html'
// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
-// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show fields'
+// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 13 fields'
pub struct BigPubStruct {
pub a: usize,
pub b: usize,
// @has 'toggle_item_contents/union.BigUnion.html'
// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
-// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show fields'
+// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 13 fields'
pub union BigUnion {
pub a: usize,
pub b: usize,
// @has 'toggle_item_contents/enum.Enum.html'
// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
-// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show fields'
+// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 2 fields'
pub enum Enum {
A, B, C,
D {
}
}
+// @has 'toggle_item_contents/enum.EnumStructVariant.html'
+// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
+// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 1 field'
+pub enum EnumStructVariant {
+ A, B, C,
+ D {
+ a: u8,
+ }
+}
+
// @has 'toggle_item_contents/enum.LargeEnum.html'
// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
-// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show variants'
+// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 13 variants'
pub enum LargeEnum {
A, B, C, D, E, F(u8), G, H, I, J, K, L, M
}
// @has 'toggle_item_contents/trait.GinormousTrait.html'
// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
-// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show associated items'
+// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 16 associated items'
pub trait GinormousTrait {
type A;
type B;
// @has 'toggle_item_contents/trait.HugeTrait.html'
// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
-// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show associated constants and methods'
+// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 12 associated constants and 2 methods'
pub trait HugeTrait {
type A;
const M: usize = 1;
fn bar();
}
+// @has 'toggle_item_contents/trait.GiganticTrait.html'
+// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
+// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 1 associated constant and 1 method'
+pub trait GiganticTrait {
+ type A;
+ type B;
+ type C;
+ type D;
+ type E;
+ type F;
+ type G;
+ type H;
+ type I;
+ type J;
+ type K;
+ type L;
+ const M: usize = 1;
+ #[must_use]
+ fn foo();
+}
+
// @has 'toggle_item_contents/trait.BigTrait.html'
// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
-// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show methods'
+// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 14 methods'
pub trait BigTrait {
type A;
#[must_use]
error: invalid format string: expected `'}'` but string was terminated
--> $DIR/session-derive-errors.rs:116:1
|
+LL | #[derive(SessionDiagnostic)]
+ | ----------------- in this derive macro expansion
LL | #[error = "E0123"]
| - because of this opening brace
LL | #[message = "This is missing a closing brace: {name"]
error: invalid format string: unmatched `}` found
--> $DIR/session-derive-errors.rs:125:1
|
+LL | #[derive(SessionDiagnostic)]
+ | ----------------- in this derive macro expansion
+LL | #[error = "E0123"]
LL | #[message = "This is missing an opening brace: name}"]
| ^ unmatched `}` in format string
|
error[E0277]: the trait bound `usize: GlobalAlloc` is not satisfied
--> $DIR/not-an-allocator.rs:2:1
|
+LL | #[global_allocator]
+ | ------------------- in this procedural macro expansion
LL | static A: usize = 0;
| ^^^^^^^^^^^^^^^^^^^^ the trait `GlobalAlloc` is not implemented for `usize`
|
- = note: required by `std::alloc::GlobalAlloc::alloc`
+note: required by `std::alloc::GlobalAlloc::alloc`
+ --> $SRC_DIR/core/src/alloc/global.rs:LL:COL
+ |
+LL | unsafe fn alloc(&self, layout: Layout) -> *mut u8;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the attribute macro `global_allocator` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `usize: GlobalAlloc` is not satisfied
--> $DIR/not-an-allocator.rs:2:1
|
+LL | #[global_allocator]
+ | ------------------- in this procedural macro expansion
LL | static A: usize = 0;
| ^^^^^^^^^^^^^^^^^^^^ the trait `GlobalAlloc` is not implemented for `usize`
|
- = note: required by `std::alloc::GlobalAlloc::dealloc`
+note: required by `std::alloc::GlobalAlloc::dealloc`
+ --> $SRC_DIR/core/src/alloc/global.rs:LL:COL
+ |
+LL | unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the attribute macro `global_allocator` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `usize: GlobalAlloc` is not satisfied
--> $DIR/not-an-allocator.rs:2:1
|
+LL | #[global_allocator]
+ | ------------------- in this procedural macro expansion
LL | static A: usize = 0;
| ^^^^^^^^^^^^^^^^^^^^ the trait `GlobalAlloc` is not implemented for `usize`
|
- = note: required by `std::alloc::GlobalAlloc::realloc`
+note: required by `std::alloc::GlobalAlloc::realloc`
+ --> $SRC_DIR/core/src/alloc/global.rs:LL:COL
+ |
+LL | unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the attribute macro `global_allocator` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `usize: GlobalAlloc` is not satisfied
--> $DIR/not-an-allocator.rs:2:1
|
+LL | #[global_allocator]
+ | ------------------- in this procedural macro expansion
LL | static A: usize = 0;
| ^^^^^^^^^^^^^^^^^^^^ the trait `GlobalAlloc` is not implemented for `usize`
|
- = note: required by `std::alloc::GlobalAlloc::alloc_zeroed`
+note: required by `std::alloc::GlobalAlloc::alloc_zeroed`
+ --> $SRC_DIR/core/src/alloc/global.rs:LL:COL
+ |
+LL | unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the attribute macro `global_allocator` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 4 previous errors
LL | static A: System = System;
| -------------------------- previous global allocator defined here
LL | #[global_allocator]
+ | ------------------- in this procedural macro expansion
LL | static B: System = System;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot define a new global allocator
|
error[E0277]: the trait bound `i32: Foo` is not satisfied
--> $DIR/associated-const-array-len.rs:5:16
|
-LL | const ID: usize;
- | ---------------- required by `Foo::ID`
-...
LL | const X: [i32; <i32 as Foo>::ID] = [0, 1, 2];
| ^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `i32`
+ |
+note: required by `Foo::ID`
+ --> $DIR/associated-const-array-len.rs:2:5
+ |
+LL | const ID: usize;
+ | ^^^^^^^^^^^^^^^^
error: aborting due to previous error
error[E0624]: associated constant `ID` is private
--> $DIR/associated-const-private-impl.rs:13:30
|
+LL | const ID: i32 = 1;
+ | ------------------ private associated constant defined here
+...
LL | assert_eq!(1, bar1::Foo::ID);
| ^^ private associated constant
error[E0283]: type annotations needed
--> $DIR/issue-63496.rs:4:21
|
-LL | const C: usize;
- | --------------- required by `A::C`
-LL |
LL | fn f() -> ([u8; A::C], [u8; A::C]);
| ^^^^
| |
|
= note: cannot satisfy `_: A`
= note: associated constants cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl`
+note: required by `A::C`
+ --> $DIR/issue-63496.rs:2:5
+ |
+LL | const C: usize;
+ | ^^^^^^^^^^^^^^^
error[E0283]: type annotations needed
--> $DIR/issue-63496.rs:4:33
|
-LL | const C: usize;
- | --------------- required by `A::C`
-LL |
LL | fn f() -> ([u8; A::C], [u8; A::C]);
| ^^^^
| |
|
= note: cannot satisfy `_: A`
= note: associated constants cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl`
+note: required by `A::C`
+ --> $DIR/issue-63496.rs:2:5
+ |
+LL | const C: usize;
+ | ^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
error[E0283]: type annotations needed
--> $DIR/issue-48027.rs:3:32
|
-LL | const X: usize;
- | --------------- required by `Bar::X`
LL | fn return_n(&self) -> [u8; Bar::X];
| ^^^^^^
| |
|
= note: cannot satisfy `_: Bar`
= note: associated constants cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl`
+note: required by `Bar::X`
+ --> $DIR/issue-48027.rs:2:5
+ |
+LL | const X: usize;
+ | ^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/duplicate.rs:6:12
- |
-LL | #![feature(impl_trait_in_bindings)]
- | ^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:11:36
+ --> $DIR/duplicate.rs:10:36
|
LL | struct SI1<T: Iterator<Item: Copy, Item: Send>> { f: T }
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:13:36
+ --> $DIR/duplicate.rs:12:36
|
LL | struct SI2<T: Iterator<Item: Copy, Item: Copy>> { f: T }
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:15:39
+ --> $DIR/duplicate.rs:14:39
|
LL | struct SI3<T: Iterator<Item: 'static, Item: 'static>> { f: T }
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:17:45
+ --> $DIR/duplicate.rs:16:45
|
LL | struct SW1<T> where T: Iterator<Item: Copy, Item: Send> { f: T }
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:19:45
+ --> $DIR/duplicate.rs:18:45
|
LL | struct SW2<T> where T: Iterator<Item: Copy, Item: Copy> { f: T }
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:21:48
+ --> $DIR/duplicate.rs:20:48
|
LL | struct SW3<T> where T: Iterator<Item: 'static, Item: 'static> { f: T }
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:24:34
+ --> $DIR/duplicate.rs:23:34
|
LL | enum EI1<T: Iterator<Item: Copy, Item: Send>> { V(T) }
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:26:34
+ --> $DIR/duplicate.rs:25:34
|
LL | enum EI2<T: Iterator<Item: Copy, Item: Copy>> { V(T) }
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:28:37
+ --> $DIR/duplicate.rs:27:37
|
LL | enum EI3<T: Iterator<Item: 'static, Item: 'static>> { V(T) }
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:30:43
+ --> $DIR/duplicate.rs:29:43
|
LL | enum EW1<T> where T: Iterator<Item: Copy, Item: Send> { V(T) }
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:32:43
+ --> $DIR/duplicate.rs:31:43
|
LL | enum EW2<T> where T: Iterator<Item: Copy, Item: Copy> { V(T) }
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:34:46
+ --> $DIR/duplicate.rs:33:46
|
LL | enum EW3<T> where T: Iterator<Item: 'static, Item: 'static> { V(T) }
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:37:35
+ --> $DIR/duplicate.rs:36:35
|
LL | union UI1<T: Iterator<Item: Copy, Item: Send>> { f: T }
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:39:35
+ --> $DIR/duplicate.rs:38:35
|
LL | union UI2<T: Iterator<Item: Copy, Item: Copy>> { f: T }
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:41:38
+ --> $DIR/duplicate.rs:40:38
|
LL | union UI3<T: Iterator<Item: 'static, Item: 'static>> { f: T }
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:43:44
+ --> $DIR/duplicate.rs:42:44
|
LL | union UW1<T> where T: Iterator<Item: Copy, Item: Send> { f: T }
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:45:44
+ --> $DIR/duplicate.rs:44:44
|
LL | union UW2<T> where T: Iterator<Item: Copy, Item: Copy> { f: T }
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:47:47
+ --> $DIR/duplicate.rs:46:47
|
LL | union UW3<T> where T: Iterator<Item: 'static, Item: 'static> { f: T }
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:50:32
+ --> $DIR/duplicate.rs:49:32
|
LL | fn FI1<T: Iterator<Item: Copy, Item: Send>>() {}
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:52:32
+ --> $DIR/duplicate.rs:51:32
|
LL | fn FI2<T: Iterator<Item: Copy, Item: Copy>>() {}
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:54:35
+ --> $DIR/duplicate.rs:53:35
|
LL | fn FI3<T: Iterator<Item: 'static, Item: 'static>>() {}
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:56:43
+ --> $DIR/duplicate.rs:55:43
|
LL | fn FW1<T>() where T: Iterator<Item: Copy, Item: Send> {}
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:58:43
+ --> $DIR/duplicate.rs:57:43
|
LL | fn FW2<T>() where T: Iterator<Item: Copy, Item: Copy> {}
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:60:46
+ --> $DIR/duplicate.rs:59:46
|
LL | fn FW3<T>() where T: Iterator<Item: 'static, Item: 'static> {}
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:66:40
+ --> $DIR/duplicate.rs:65:40
|
LL | fn FAPIT1(_: impl Iterator<Item: Copy, Item: Send>) {}
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:68:40
+ --> $DIR/duplicate.rs:67:40
|
LL | fn FAPIT2(_: impl Iterator<Item: Copy, Item: Copy>) {}
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:70:43
+ --> $DIR/duplicate.rs:69:43
|
LL | fn FAPIT3(_: impl Iterator<Item: 'static, Item: 'static>) {}
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:73:39
- |
-LL | const CIT1: impl Iterator<Item: Copy, Item: Send> = iter::empty();
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:75:39
- |
-LL | const CIT2: impl Iterator<Item: Copy, Item: Copy> = iter::empty();
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:77:42
- |
-LL | const CIT3: impl Iterator<Item: 'static, Item: 'static> = iter::empty();
- | ------------- ^^^^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:79:40
- |
-LL | static SIT1: impl Iterator<Item: Copy, Item: Send> = iter::empty();
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:81:40
- |
-LL | static SIT2: impl Iterator<Item: Copy, Item: Copy> = iter::empty();
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:83:43
- |
-LL | static SIT3: impl Iterator<Item: 'static, Item: 'static> = iter::empty();
- | ------------- ^^^^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:86:46
- |
-LL | fn lit1() { let _: impl Iterator<Item: Copy, Item: Send> = iter::empty(); }
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:88:46
- |
-LL | fn lit2() { let _: impl Iterator<Item: Copy, Item: Copy> = iter::empty(); }
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:90:49
- |
-LL | fn lit3() { let _: impl Iterator<Item: 'static, Item: 'static> = iter::empty(); }
- | ------------- ^^^^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:93:35
+ --> $DIR/duplicate.rs:72:35
|
LL | type TAI1<T: Iterator<Item: Copy, Item: Send>> = T;
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:95:35
+ --> $DIR/duplicate.rs:74:35
|
LL | type TAI2<T: Iterator<Item: Copy, Item: Copy>> = T;
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:97:38
+ --> $DIR/duplicate.rs:76:38
|
LL | type TAI3<T: Iterator<Item: 'static, Item: 'static>> = T;
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:99:44
+ --> $DIR/duplicate.rs:78:44
|
LL | type TAW1<T> where T: Iterator<Item: Copy, Item: Send> = T;
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:101:44
+ --> $DIR/duplicate.rs:80:44
|
LL | type TAW2<T> where T: Iterator<Item: Copy, Item: Copy> = T;
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:103:47
+ --> $DIR/duplicate.rs:82:47
|
LL | type TAW3<T> where T: Iterator<Item: 'static, Item: 'static> = T;
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:106:36
+ --> $DIR/duplicate.rs:85:36
|
LL | type ETAI1<T: Iterator<Item: Copy, Item: Send>> = impl Copy;
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:108:36
+ --> $DIR/duplicate.rs:87:36
|
LL | type ETAI2<T: Iterator<Item: Copy, Item: Copy>> = impl Copy;
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:110:39
+ --> $DIR/duplicate.rs:89:39
|
LL | type ETAI3<T: Iterator<Item: 'static, Item: 'static>> = impl Copy;
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:112:40
+ --> $DIR/duplicate.rs:91:40
|
LL | type ETAI4 = impl Iterator<Item: Copy, Item: Send>;
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:114:40
+ --> $DIR/duplicate.rs:93:40
|
LL | type ETAI5 = impl Iterator<Item: Copy, Item: Copy>;
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:116:43
+ --> $DIR/duplicate.rs:95:43
|
LL | type ETAI6 = impl Iterator<Item: 'static, Item: 'static>;
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:119:36
+ --> $DIR/duplicate.rs:98:36
|
LL | trait TRI1<T: Iterator<Item: Copy, Item: Send>> {}
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:121:36
+ --> $DIR/duplicate.rs:100:36
|
LL | trait TRI2<T: Iterator<Item: Copy, Item: Copy>> {}
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:123:39
+ --> $DIR/duplicate.rs:102:39
|
LL | trait TRI3<T: Iterator<Item: 'static, Item: 'static>> {}
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:125:34
+ --> $DIR/duplicate.rs:104:34
|
LL | trait TRS1: Iterator<Item: Copy, Item: Send> {}
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:127:34
+ --> $DIR/duplicate.rs:106:34
|
LL | trait TRS2: Iterator<Item: Copy, Item: Copy> {}
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:129:37
+ --> $DIR/duplicate.rs:108:37
|
LL | trait TRS3: Iterator<Item: 'static, Item: 'static> {}
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:131:45
+ --> $DIR/duplicate.rs:110:45
|
LL | trait TRW1<T> where T: Iterator<Item: Copy, Item: Send> {}
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:133:45
+ --> $DIR/duplicate.rs:112:45
|
LL | trait TRW2<T> where T: Iterator<Item: Copy, Item: Copy> {}
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:135:48
+ --> $DIR/duplicate.rs:114:48
|
LL | trait TRW3<T> where T: Iterator<Item: 'static, Item: 'static> {}
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:137:46
+ --> $DIR/duplicate.rs:116:46
|
LL | trait TRSW1 where Self: Iterator<Item: Copy, Item: Send> {}
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:137:46
+ --> $DIR/duplicate.rs:116:46
|
LL | trait TRSW1 where Self: Iterator<Item: Copy, Item: Send> {}
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:140:46
+ --> $DIR/duplicate.rs:119:46
|
LL | trait TRSW2 where Self: Iterator<Item: Copy, Item: Copy> {}
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:140:46
+ --> $DIR/duplicate.rs:119:46
|
LL | trait TRSW2 where Self: Iterator<Item: Copy, Item: Copy> {}
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:143:49
+ --> $DIR/duplicate.rs:122:49
|
LL | trait TRSW3 where Self: Iterator<Item: 'static, Item: 'static> {}
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:143:49
+ --> $DIR/duplicate.rs:122:49
|
LL | trait TRSW3 where Self: Iterator<Item: 'static, Item: 'static> {}
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:153:40
+ --> $DIR/duplicate.rs:132:40
|
LL | type TADyn1 = dyn Iterator<Item: Copy, Item: Send>;
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:155:44
+ --> $DIR/duplicate.rs:134:44
|
LL | type TADyn2 = Box<dyn Iterator<Item: Copy, Item: Copy>>;
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:157:43
+ --> $DIR/duplicate.rs:136:43
|
LL | type TADyn3 = dyn Iterator<Item: 'static, Item: 'static>;
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:146:43
+ --> $DIR/duplicate.rs:125:43
|
LL | trait TRA1 { type A: Iterator<Item: Copy, Item: Send>; }
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:148:43
+ --> $DIR/duplicate.rs:127:43
|
LL | trait TRA2 { type A: Iterator<Item: Copy, Item: Copy>; }
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:150:46
+ --> $DIR/duplicate.rs:129:46
|
LL | trait TRA3 { type A: Iterator<Item: 'static, Item: 'static>; }
| ------------- ^^^^^^^^^^^^^ re-bound here
| |
| `Item` bound here first
-error: aborting due to 69 previous errors; 2 warnings emitted
+error: aborting due to 60 previous errors; 1 warning emitted
For more information about this error, try `rustc --explain E0719`.
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/duplicate.rs:6:12
- |
-LL | #![feature(impl_trait_in_bindings)]
- | ^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: `#[warn(incomplete_features)]` on by default
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:11:36
+ --> $DIR/duplicate.rs:10:36
|
LL | struct SI1<T: Iterator<Item: Copy, Item: Send>> { f: T }
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:13:36
+ --> $DIR/duplicate.rs:12:36
|
LL | struct SI2<T: Iterator<Item: Copy, Item: Copy>> { f: T }
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:15:39
+ --> $DIR/duplicate.rs:14:39
|
LL | struct SI3<T: Iterator<Item: 'static, Item: 'static>> { f: T }
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:17:45
+ --> $DIR/duplicate.rs:16:45
|
LL | struct SW1<T> where T: Iterator<Item: Copy, Item: Send> { f: T }
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:19:45
+ --> $DIR/duplicate.rs:18:45
|
LL | struct SW2<T> where T: Iterator<Item: Copy, Item: Copy> { f: T }
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:21:48
+ --> $DIR/duplicate.rs:20:48
|
LL | struct SW3<T> where T: Iterator<Item: 'static, Item: 'static> { f: T }
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:24:34
+ --> $DIR/duplicate.rs:23:34
|
LL | enum EI1<T: Iterator<Item: Copy, Item: Send>> { V(T) }
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:26:34
+ --> $DIR/duplicate.rs:25:34
|
LL | enum EI2<T: Iterator<Item: Copy, Item: Copy>> { V(T) }
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:28:37
+ --> $DIR/duplicate.rs:27:37
|
LL | enum EI3<T: Iterator<Item: 'static, Item: 'static>> { V(T) }
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:30:43
+ --> $DIR/duplicate.rs:29:43
|
LL | enum EW1<T> where T: Iterator<Item: Copy, Item: Send> { V(T) }
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:32:43
+ --> $DIR/duplicate.rs:31:43
|
LL | enum EW2<T> where T: Iterator<Item: Copy, Item: Copy> { V(T) }
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:34:46
+ --> $DIR/duplicate.rs:33:46
|
LL | enum EW3<T> where T: Iterator<Item: 'static, Item: 'static> { V(T) }
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:37:35
+ --> $DIR/duplicate.rs:36:35
|
LL | union UI1<T: Iterator<Item: Copy, Item: Send>> { f: T }
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:39:35
+ --> $DIR/duplicate.rs:38:35
|
LL | union UI2<T: Iterator<Item: Copy, Item: Copy>> { f: T }
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:41:38
+ --> $DIR/duplicate.rs:40:38
|
LL | union UI3<T: Iterator<Item: 'static, Item: 'static>> { f: T }
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:43:44
+ --> $DIR/duplicate.rs:42:44
|
LL | union UW1<T> where T: Iterator<Item: Copy, Item: Send> { f: T }
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:45:44
+ --> $DIR/duplicate.rs:44:44
|
LL | union UW2<T> where T: Iterator<Item: Copy, Item: Copy> { f: T }
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:47:47
+ --> $DIR/duplicate.rs:46:47
|
LL | union UW3<T> where T: Iterator<Item: 'static, Item: 'static> { f: T }
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:50:32
+ --> $DIR/duplicate.rs:49:32
|
LL | fn FI1<T: Iterator<Item: Copy, Item: Send>>() {}
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:52:32
+ --> $DIR/duplicate.rs:51:32
|
LL | fn FI2<T: Iterator<Item: Copy, Item: Copy>>() {}
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:54:35
+ --> $DIR/duplicate.rs:53:35
|
LL | fn FI3<T: Iterator<Item: 'static, Item: 'static>>() {}
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:56:43
+ --> $DIR/duplicate.rs:55:43
|
LL | fn FW1<T>() where T: Iterator<Item: Copy, Item: Send> {}
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:58:43
+ --> $DIR/duplicate.rs:57:43
|
LL | fn FW2<T>() where T: Iterator<Item: Copy, Item: Copy> {}
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:60:46
+ --> $DIR/duplicate.rs:59:46
|
LL | fn FW3<T>() where T: Iterator<Item: 'static, Item: 'static> {}
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:66:40
+ --> $DIR/duplicate.rs:65:40
|
LL | fn FAPIT1(_: impl Iterator<Item: Copy, Item: Send>) {}
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:68:40
+ --> $DIR/duplicate.rs:67:40
|
LL | fn FAPIT2(_: impl Iterator<Item: Copy, Item: Copy>) {}
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:70:43
+ --> $DIR/duplicate.rs:69:43
|
LL | fn FAPIT3(_: impl Iterator<Item: 'static, Item: 'static>) {}
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:73:39
- |
-LL | const CIT1: impl Iterator<Item: Copy, Item: Send> = iter::empty();
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:75:39
- |
-LL | const CIT2: impl Iterator<Item: Copy, Item: Copy> = iter::empty();
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:77:42
- |
-LL | const CIT3: impl Iterator<Item: 'static, Item: 'static> = iter::empty();
- | ------------- ^^^^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:79:40
- |
-LL | static SIT1: impl Iterator<Item: Copy, Item: Send> = iter::empty();
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:81:40
- |
-LL | static SIT2: impl Iterator<Item: Copy, Item: Copy> = iter::empty();
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:83:43
- |
-LL | static SIT3: impl Iterator<Item: 'static, Item: 'static> = iter::empty();
- | ------------- ^^^^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:86:46
- |
-LL | fn lit1() { let _: impl Iterator<Item: Copy, Item: Send> = iter::empty(); }
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:88:46
- |
-LL | fn lit2() { let _: impl Iterator<Item: Copy, Item: Copy> = iter::empty(); }
- | ---------- ^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:90:49
- |
-LL | fn lit3() { let _: impl Iterator<Item: 'static, Item: 'static> = iter::empty(); }
- | ------------- ^^^^^^^^^^^^^ re-bound here
- | |
- | `Item` bound here first
-
-error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:93:35
+ --> $DIR/duplicate.rs:72:35
|
LL | type TAI1<T: Iterator<Item: Copy, Item: Send>> = T;
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:95:35
+ --> $DIR/duplicate.rs:74:35
|
LL | type TAI2<T: Iterator<Item: Copy, Item: Copy>> = T;
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:97:38
+ --> $DIR/duplicate.rs:76:38
|
LL | type TAI3<T: Iterator<Item: 'static, Item: 'static>> = T;
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:99:44
+ --> $DIR/duplicate.rs:78:44
|
LL | type TAW1<T> where T: Iterator<Item: Copy, Item: Send> = T;
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:101:44
+ --> $DIR/duplicate.rs:80:44
|
LL | type TAW2<T> where T: Iterator<Item: Copy, Item: Copy> = T;
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:103:47
+ --> $DIR/duplicate.rs:82:47
|
LL | type TAW3<T> where T: Iterator<Item: 'static, Item: 'static> = T;
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:106:36
+ --> $DIR/duplicate.rs:85:36
|
LL | type ETAI1<T: Iterator<Item: Copy, Item: Send>> = impl Copy;
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:108:36
+ --> $DIR/duplicate.rs:87:36
|
LL | type ETAI2<T: Iterator<Item: Copy, Item: Copy>> = impl Copy;
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:110:39
+ --> $DIR/duplicate.rs:89:39
|
LL | type ETAI3<T: Iterator<Item: 'static, Item: 'static>> = impl Copy;
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:112:40
+ --> $DIR/duplicate.rs:91:40
|
LL | type ETAI4 = impl Iterator<Item: Copy, Item: Send>;
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:114:40
+ --> $DIR/duplicate.rs:93:40
|
LL | type ETAI5 = impl Iterator<Item: Copy, Item: Copy>;
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:116:43
+ --> $DIR/duplicate.rs:95:43
|
LL | type ETAI6 = impl Iterator<Item: 'static, Item: 'static>;
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:119:36
+ --> $DIR/duplicate.rs:98:36
|
LL | trait TRI1<T: Iterator<Item: Copy, Item: Send>> {}
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:121:36
+ --> $DIR/duplicate.rs:100:36
|
LL | trait TRI2<T: Iterator<Item: Copy, Item: Copy>> {}
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:123:39
+ --> $DIR/duplicate.rs:102:39
|
LL | trait TRI3<T: Iterator<Item: 'static, Item: 'static>> {}
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:125:34
+ --> $DIR/duplicate.rs:104:34
|
LL | trait TRS1: Iterator<Item: Copy, Item: Send> {}
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:127:34
+ --> $DIR/duplicate.rs:106:34
|
LL | trait TRS2: Iterator<Item: Copy, Item: Copy> {}
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:129:37
+ --> $DIR/duplicate.rs:108:37
|
LL | trait TRS3: Iterator<Item: 'static, Item: 'static> {}
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:131:45
+ --> $DIR/duplicate.rs:110:45
|
LL | trait TRW1<T> where T: Iterator<Item: Copy, Item: Send> {}
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:133:45
+ --> $DIR/duplicate.rs:112:45
|
LL | trait TRW2<T> where T: Iterator<Item: Copy, Item: Copy> {}
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:135:48
+ --> $DIR/duplicate.rs:114:48
|
LL | trait TRW3<T> where T: Iterator<Item: 'static, Item: 'static> {}
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:137:46
+ --> $DIR/duplicate.rs:116:46
|
LL | trait TRSW1 where Self: Iterator<Item: Copy, Item: Send> {}
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:137:46
+ --> $DIR/duplicate.rs:116:46
|
LL | trait TRSW1 where Self: Iterator<Item: Copy, Item: Send> {}
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:140:46
+ --> $DIR/duplicate.rs:119:46
|
LL | trait TRSW2 where Self: Iterator<Item: Copy, Item: Copy> {}
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:140:46
+ --> $DIR/duplicate.rs:119:46
|
LL | trait TRSW2 where Self: Iterator<Item: Copy, Item: Copy> {}
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:143:49
+ --> $DIR/duplicate.rs:122:49
|
LL | trait TRSW3 where Self: Iterator<Item: 'static, Item: 'static> {}
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:143:49
+ --> $DIR/duplicate.rs:122:49
|
LL | trait TRSW3 where Self: Iterator<Item: 'static, Item: 'static> {}
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:153:40
+ --> $DIR/duplicate.rs:132:40
|
LL | type TADyn1 = dyn Iterator<Item: Copy, Item: Send>;
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:155:44
+ --> $DIR/duplicate.rs:134:44
|
LL | type TADyn2 = Box<dyn Iterator<Item: Copy, Item: Copy>>;
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:157:43
+ --> $DIR/duplicate.rs:136:43
|
LL | type TADyn3 = dyn Iterator<Item: 'static, Item: 'static>;
| ------------- ^^^^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:146:43
+ --> $DIR/duplicate.rs:125:43
|
LL | trait TRA1 { type A: Iterator<Item: Copy, Item: Send>; }
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:148:43
+ --> $DIR/duplicate.rs:127:43
|
LL | trait TRA2 { type A: Iterator<Item: Copy, Item: Copy>; }
| ---------- ^^^^^^^^^^ re-bound here
| `Item` bound here first
error[E0719]: the value of the associated type `Item` (from trait `Iterator`) is already specified
- --> $DIR/duplicate.rs:150:46
+ --> $DIR/duplicate.rs:129:46
|
LL | trait TRA3 { type A: Iterator<Item: 'static, Item: 'static>; }
| ------------- ^^^^^^^^^^^^^ re-bound here
| |
| `Item` bound here first
-error: aborting due to 69 previous errors; 1 warning emitted
+error: aborting due to 60 previous errors
For more information about this error, try `rustc --explain E0719`.
#![feature(min_type_alias_impl_trait)]
#![cfg_attr(full_tait, feature(type_alias_impl_trait))]
//[full_tait]~^ WARN incomplete
-#![feature(impl_trait_in_bindings)] //~ WARN the feature `impl_trait_in_bindings` is incomplete
#![feature(untagged_unions)]
use std::iter;
fn FAPIT3(_: impl Iterator<Item: 'static, Item: 'static>) {}
//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
-const CIT1: impl Iterator<Item: Copy, Item: Send> = iter::empty();
-//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
-const CIT2: impl Iterator<Item: Copy, Item: Copy> = iter::empty();
-//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
-const CIT3: impl Iterator<Item: 'static, Item: 'static> = iter::empty();
-//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
-static SIT1: impl Iterator<Item: Copy, Item: Send> = iter::empty();
-//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
-static SIT2: impl Iterator<Item: Copy, Item: Copy> = iter::empty();
-//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
-static SIT3: impl Iterator<Item: 'static, Item: 'static> = iter::empty();
-//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
-
-fn lit1() { let _: impl Iterator<Item: Copy, Item: Send> = iter::empty(); }
-//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
-fn lit2() { let _: impl Iterator<Item: Copy, Item: Copy> = iter::empty(); }
-//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
-fn lit3() { let _: impl Iterator<Item: 'static, Item: 'static> = iter::empty(); }
-//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
-
type TAI1<T: Iterator<Item: Copy, Item: Send>> = T;
//~^ ERROR the value of the associated type `Item` (from trait `Iterator`) is already specified [E0719]
type TAI2<T: Iterator<Item: Copy, Item: Copy>> = T;
+++ /dev/null
-// run-pass
-
-#![feature(associated_type_bounds)]
-#![feature(impl_trait_in_bindings)]
-//~^ WARNING `impl_trait_in_bindings` is incomplete
-#![allow(non_upper_case_globals)]
-
-use std::ops::Add;
-
-trait Tr1 { type As1; fn mk(&self) -> Self::As1; }
-trait Tr2<'a> { fn tr2(self) -> &'a Self; }
-
-fn assert_copy<T: Copy>(x: T) { let _x = x; let _x = x; }
-fn assert_static<T: 'static>(_: T) {}
-fn assert_forall_tr2<T: for<'a> Tr2<'a>>(_: T) {}
-
-#[derive(Copy, Clone)]
-struct S1;
-#[derive(Copy, Clone)]
-struct S2;
-impl Tr1 for S1 { type As1 = S2; fn mk(&self) -> Self::As1 { S2 } }
-
-const cdef_et1: &dyn Tr1<As1: Copy> = &S1;
-const sdef_et1: &dyn Tr1<As1: Copy> = &S1;
-pub fn use_et1() { assert_copy(cdef_et1.mk()); assert_copy(sdef_et1.mk()); }
-
-const cdef_et2: &(dyn Tr1<As1: 'static> + Sync) = &S1;
-static sdef_et2: &(dyn Tr1<As1: 'static> + Sync) = &S1;
-pub fn use_et2() { assert_static(cdef_et2.mk()); assert_static(sdef_et2.mk()); }
-
-const cdef_et3: &dyn Tr1<As1: Clone + Iterator<Item: Add<u8, Output: Into<u8>>>> = {
- struct A;
- impl Tr1 for A {
- type As1 = core::ops::Range<u8>;
- fn mk(&self) -> Self::As1 { 0..10 }
- }
- &A
-};
-pub fn use_et3() {
- let _0 = cdef_et3.mk().clone();
- let mut s = 0u8;
- for _1 in _0 {
- let _2 = _1 + 1u8;
- s += _2.into();
- }
- assert_eq!(s, (0..10).map(|x| x + 1).sum());
-}
-
-const cdef_et4: &(dyn Tr1<As1: for<'a> Tr2<'a>> + Sync) = {
- #[derive(Copy, Clone)]
- struct A;
- impl Tr1 for A {
- type As1 = A;
- fn mk(&self) -> A { A }
- }
- impl<'a> Tr2<'a> for A {
- fn tr2(self) -> &'a Self { &A }
- }
- &A
-};
-static sdef_et4: &(dyn Tr1<As1: for<'a> Tr2<'a>> + Sync) = cdef_et4;
-pub fn use_et4() { assert_forall_tr2(cdef_et4.mk()); assert_forall_tr2(sdef_et4.mk()); }
-
-fn main() {
- let _ = use_et1();
- let _ = use_et2();
- let _ = use_et3();
- let _ = use_et4();
-}
+++ /dev/null
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/dyn-lcsit.rs:4:12
- |
-LL | #![feature(impl_trait_in_bindings)]
- | ^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: `#[warn(incomplete_features)]` on by default
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
-warning: 1 warning emitted
-
+++ /dev/null
-// run-pass
-
-#![feature(associated_type_bounds)]
-#![feature(impl_trait_in_bindings)]
-//~^ WARNING `impl_trait_in_bindings` is incomplete
-#![allow(non_upper_case_globals)]
-
-use std::ops::Add;
-
-trait Tr1 { type As1; fn mk(&self) -> Self::As1; }
-trait Tr2<'a> { fn tr2(self) -> &'a Self; }
-
-fn assert_copy<T: Copy>(x: T) { let _x = x; let _x = x; }
-fn assert_static<T: 'static>(_: T) {}
-fn assert_forall_tr2<T: for<'a> Tr2<'a>>(_: T) {}
-
-#[derive(Copy, Clone)]
-struct S1;
-#[derive(Copy, Clone)]
-struct S2;
-impl Tr1 for S1 { type As1 = S2; fn mk(&self) -> Self::As1 { S2 } }
-
-const cdef_et1: impl Copy + Tr1<As1: Copy> = {
- let x: impl Copy + Tr1<As1: Copy> = S1;
- x
-};
-static sdef_et1: impl Copy + Tr1<As1: Copy> = cdef_et1;
-pub fn use_et1() { assert_copy(cdef_et1.mk()); assert_copy(sdef_et1.mk()); }
-
-const cdef_et2: impl Tr1<As1: 'static> = {
- let x: impl Tr1<As1: 'static> = S1;
- x
-};
-static sdef_et2: impl Tr1<As1: 'static> = cdef_et2;
-pub fn use_et2() { assert_static(cdef_et2.mk()); assert_static(sdef_et2.mk()); }
-
-const cdef_et3: impl Tr1<As1: Clone + Iterator<Item: Add<u8, Output: Into<u8>>>> = {
- struct A;
- impl Tr1 for A {
- type As1 = core::ops::Range<u8>;
- fn mk(&self) -> Self::As1 { 0..10 }
- }
- let x: impl Tr1<As1: Clone + Iterator<Item: Add<u8, Output: Into<u8>>>> = A;
- x
-};
-pub fn use_et3() {
- let _0 = cdef_et3.mk().clone();
- let mut s = 0u8;
- for _1 in _0 {
- let _2 = _1 + 1u8;
- s += _2.into();
- }
- assert_eq!(s, (0..10).map(|x| x + 1).sum());
-}
-
-const cdef_et4: impl Copy + Tr1<As1: for<'a> Tr2<'a>> = {
- #[derive(Copy, Clone)]
- struct A;
- impl Tr1 for A {
- type As1 = A;
- fn mk(&self) -> A { A }
- }
- impl<'a> Tr2<'a> for A {
- fn tr2(self) -> &'a Self { &A }
- }
- let x: impl Copy + Tr1<As1: for<'a> Tr2<'a>> = A;
- x
-};
-
-static sdef_et4: impl Copy + Tr1<As1: for<'a> Tr2<'a>> = cdef_et4;
-pub fn use_et4() { assert_forall_tr2(cdef_et4.mk()); assert_forall_tr2(sdef_et4.mk()); }
-
-fn main() {
- let _ = use_et1();
- let _ = use_et2();
- let _ = use_et3();
- let _ = use_et4();
-}
+++ /dev/null
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/lcsit.rs:4:12
- |
-LL | #![feature(impl_trait_in_bindings)]
- | ^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: `#[warn(incomplete_features)]` on by default
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
-warning: 1 warning emitted
-
error[E0277]: the trait bound `<G as GetToInt>::R: ToInt` is not satisfied
--> $DIR/associated-types-bound-failure.rs:19:19
|
-LL | fn to_int(&self) -> isize;
- | -------------------------- required by `ToInt::to_int`
-...
LL | ToInt::to_int(&g.get())
| ^^^^^^^^ the trait `ToInt` is not implemented for `<G as GetToInt>::R`
|
+note: required by `ToInt::to_int`
+ --> $DIR/associated-types-bound-failure.rs:6:5
+ |
+LL | fn to_int(&self) -> isize;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
help: consider further restricting the associated type
|
LL | where G : GetToInt, <G as GetToInt>::R: ToInt
error[E0277]: the trait bound `Self: Get` is not satisfied
- --> $DIR/associated-types-for-unimpl-trait.rs:10:8
+ --> $DIR/associated-types-for-unimpl-trait.rs:10:40
|
+LL | trait Get {
+ | --------- required by this bound in `Get`
+...
LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
- | ^^^^ the trait `Get` is not implemented for `Self`
+ | ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
|
help: consider further restricting `Self`
|
error[E0277]: the trait bound `T: Get` is not satisfied
- --> $DIR/associated-types-no-suitable-bound.rs:11:8
+ --> $DIR/associated-types-no-suitable-bound.rs:11:21
|
+LL | trait Get {
+ | --------- required by this bound in `Get`
+...
LL | fn uhoh<T>(foo: <T as Get>::Value) {}
- | ^^^^ the trait `Get` is not implemented for `T`
+ | ^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `T`
|
help: consider restricting type parameter `T`
|
error[E0277]: the trait bound `Self: Get` is not satisfied
- --> $DIR/associated-types-no-suitable-supertrait-2.rs:17:8
+ --> $DIR/associated-types-no-suitable-supertrait-2.rs:17:40
|
+LL | trait Get {
+ | --------- required by this bound in `Get`
+...
LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
- | ^^^^ the trait `Get` is not implemented for `Self`
+ | ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
|
help: consider further restricting `Self`
|
error[E0277]: the trait bound `Self: Get` is not satisfied
- --> $DIR/associated-types-no-suitable-supertrait.rs:17:8
+ --> $DIR/associated-types-no-suitable-supertrait.rs:17:40
|
+LL | trait Get {
+ | --------- required by this bound in `Get`
+...
LL | fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
- | ^^^^ the trait `Get` is not implemented for `Self`
+ | ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
|
help: consider further restricting `Self`
|
| ^^^^^^^^^^^^^^^
error[E0277]: the trait bound `(T, U): Get` is not satisfied
- --> $DIR/associated-types-no-suitable-supertrait.rs:22:8
+ --> $DIR/associated-types-no-suitable-supertrait.rs:22:40
|
+LL | trait Get {
+ | --------- required by this bound in `Get`
+...
LL | fn uhoh<U:Get>(&self, foo: U, bar: <(T, U) as Get>::Value) {}
- | ^^^^ the trait `Get` is not implemented for `(T, U)`
+ | ^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `(T, U)`
error: aborting due to 2 previous errors
error[E0277]: the trait bound `Self: Get` is not satisfied
- --> $DIR/associated-types-projection-to-unrelated-trait-in-method-without-default.rs:10:8
+ --> $DIR/associated-types-projection-to-unrelated-trait-in-method-without-default.rs:10:40
|
+LL | trait Get {
+ | --------- required by this bound in `Get`
+...
LL | fn okay<U:Get>(&self, foo: U, bar: <Self as Get>::Value);
- | ^^^^ the trait `Get` is not implemented for `Self`
+ | ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
|
help: consider further restricting `Self`
|
error[E0283]: type annotations needed
--> $DIR/associated-types-unconstrained.rs:14:20
|
-LL | fn bar() -> isize;
- | ------------------ required by `Foo::bar`
-...
LL | let x: isize = Foo::bar();
| ^^^^^^^^ cannot infer type
|
= note: cannot satisfy `_: Foo`
+note: required by `Foo::bar`
+ --> $DIR/associated-types-unconstrained.rs:5:5
+ |
+LL | fn bar() -> isize;
+ | ^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
}
impl<T: Copy + std::ops::Deref> UnsafeCopy<'_, T> for T {
- //~^ ERROR the trait bound `<T as UnsafeCopy<'b, T>>::Item: Deref` is not satisfied
+ //~^ ERROR the trait bound `for<'b> <T as UnsafeCopy<'b, T>>::Item: Deref` is not satisfied
type Item = T;
//~^ ERROR the trait bound `for<'b> <T as UnsafeCopy<'b, T>>::Item: Deref
}
<&T as Deref>
<&mut T as Deref>
-error[E0277]: the trait bound `<T as UnsafeCopy<'b, T>>::Item: Deref` is not satisfied
+error[E0277]: the trait bound `for<'b> <T as UnsafeCopy<'b, T>>::Item: Deref` is not satisfied
--> $DIR/hr-associated-type-projection-1.rs:13:33
|
LL | impl<T: Copy + std::ops::Deref> UnsafeCopy<'_, T> for T {
- | ^^^^^^^^^^^^^^^^^ the trait `Deref` is not implemented for `<T as UnsafeCopy<'b, T>>::Item`
+ | ^^^^^^^^^^^^^^^^^ the trait `for<'b> Deref` is not implemented for `<T as UnsafeCopy<'b, T>>::Item`
|
help: consider further restricting the associated type
|
-LL | impl<T: Copy + std::ops::Deref> UnsafeCopy<'_, T> for T where <T as UnsafeCopy<'b, T>>::Item: Deref {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | impl<T: Copy + std::ops::Deref> UnsafeCopy<'_, T> for T where for<'b> <T as UnsafeCopy<'b, T>>::Item: Deref {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
error[E0271]: type mismatch resolving `<() as Array>::Element == &()`
--> $DIR/issue-44153.rs:18:5
|
-LL | fn visit() {}
- | ---------- required by `Visit::visit`
-...
LL | <() as Visit>::visit();
| ^^^^^^^^^^^^^^^^^^^^ expected `&()`, found `()`
|
|
LL | impl<'a> Visit for () where
| ^^^^^ ^^
+note: required by `Visit::visit`
+ --> $DIR/issue-44153.rs:6:5
+ |
+LL | fn visit() {}
+ | ^^^^^^^^^^
error: aborting due to previous error
|
LL | async fn error(lt: HasLifetime) {
| ^^^^^^^^^^^- help: indicate the anonymous lifetime: `<'_>`
+ |
+ = note: assuming a `'static` lifetime...
error: aborting due to previous error
| ^^^^^^ the `?` operator cannot be applied to type `impl Future`
|
= help: the trait `Try` is not implemented for `impl Future`
- = note: required by `branch`
+note: required by `branch`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: consider `await`ing on the `Future`
|
LL | foo().await?;
| ^^ the `?` operator cannot be applied to type `T`
|
= help: the trait `Try` is not implemented for `T`
- = note: required by `branch`
+note: required by `branch`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: consider `await`ing on the `Future`
|
LL | t.await?;
| ^^^^^^^^ `()` is not a future
|
= help: the trait `Future` is not implemented for `()`
- = note: required by `poll`
+note: required by `poll`
+ --> $SRC_DIR/core/src/future/future.rs:LL:COL
+ |
+LL | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 4 previous errors
| ^^^^^^^ the `?` operator cannot be applied to type `impl Future`
|
= help: the trait `Try` is not implemented for `impl Future`
- = note: required by `branch`
+note: required by `branch`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the `?` operator can only be used in an async function that returns `Result` or `Option` (or another type that implements `FromResidual`)
--> $DIR/issue-84841.rs:9:11
| |_- this function should return `Result` or `Option` to accept `?`
|
= help: the trait `FromResidual<_>` is not implemented for `()`
- = note: required by `from_residual`
+note: required by `from_residual`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn from_residual(residual: R) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
| ^^^^^^^^^^^^^^^^ `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]` is not a future
|
= help: the trait `Future` is not implemented for `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]`
- = note: required by `poll`
+note: required by `poll`
+ --> $SRC_DIR/core/src/future/future.rs:LL:COL
+ |
+LL | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 4 previous errors
|
LL | struct Sleep(std::marker::PhantomPinned);
| ^^^^^
- = note: required by `Pin::<P>::new`
+note: required by `Pin::<P>::new`
+ --> $SRC_DIR/core/src/pin.rs:LL:COL
+ |
+LL | pub const fn new(pointer: P) -> Pin<P> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
| |_____- this function should return `Result` or `Option` to accept `?`
|
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `{integer}`
- = note: required by `from_residual`
+note: required by `from_residual`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn from_residual(residual: R) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the `?` operator can only be used in an async closure that returns `Result` or `Option` (or another type that implements `FromResidual`)
--> $DIR/try-on-option-in-async.rs:17:10
| |_____- this function should return `Result` or `Option` to accept `?`
|
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `u32`
- = note: required by `from_residual`
+note: required by `from_residual`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn from_residual(residual: R) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the `?` operator can only be used in an async function that returns `Result` or `Option` (or another type that implements `FromResidual`)
--> $DIR/try-on-option-in-async.rs:26:6
| |_- this function should return `Result` or `Option` to accept `?`
|
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `u32`
- = note: required by `from_residual`
+note: required by `from_residual`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn from_residual(residual: R) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 3 previous errors
| ^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `[u8]`
- = note: required by `Box::<T, A>::into_boxed_slice`
+note: required by `Box::<T, A>::into_boxed_slice`
+ --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ |
+LL | pub fn into_boxed_slice(boxed: Self) -> Box<[T], A> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/into-boxed-slice-fail.rs:7:13
| ^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `dyn Debug`
- = note: required by `Box::<T, A>::into_boxed_slice`
+note: required by `Box::<T, A>::into_boxed_slice`
+ --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ |
+LL | pub fn into_boxed_slice(boxed: Self) -> Box<[T], A> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the size for values of type `dyn Debug` cannot be known at compilation time
--> $DIR/into-boxed-slice-fail.rs:11:13
error[E0277]: the trait bound `{float}: Foo` is not satisfied
--> $DIR/type_wf.rs:18:13
|
-LL | struct S<T: Foo> {
- | ---------------- required by `S`
-...
LL | let s = S {
| ^ the trait `Foo` is not implemented for `{float}`
|
= help: the following implementations were found:
<Option<T> as Foo>
<i32 as Foo>
+note: required by `S`
+ --> $DIR/type_wf.rs:6:1
+ |
+LL | struct S<T: Foo> {
+ | ^^^^^^^^^^^^^^^^
error: aborting due to previous error
| ^^------^
| | |
| | found signature of `fn(u16) -> _`
- | expected signature of `fn(<u32 as T<'x>>::V) -> _`
+ | expected signature of `for<'x> fn(<u32 as T<'x>>::V) -> _`
|
= note: required for the cast to the object type `dyn for<'x> Fn(<u32 as T<'x>>::V)`
-error[E0119]: conflicting implementations of trait `Trait` for type `for<'r> fn(fn(&'r ()))`
+error[E0119]: conflicting implementations of trait `Trait` for type `for<'r> fn(for<'r> fn(&'r ()))`
--> $DIR/coherence-fn-covariant-bound-vs-static.rs:17:1
|
LL | impl Trait for for<'r> fn(fn(&'r ())) {}
| ------------------------------------- first implementation here
LL | impl<'a> Trait for fn(fn(&'a ())) {}
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'r> fn(fn(&'r ()))`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'r> fn(for<'r> fn(&'r ()))`
|
= note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details
error[E0038]: the trait `Foo` cannot be made into an object
- --> $DIR/object-safety-err-ret.rs:17:15
+ --> $DIR/object-safety-err-ret.rs:17:16
|
LL | fn use_dyn(v: &dyn Foo) {
- | ^^^^^^^^ `Foo` cannot be made into an object
+ | ^^^^^^^ `Foo` cannot be made into an object
|
= help: consider moving `test` to another trait
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>
|
LL | <[Adt; std::mem::size_of::<Self::Assoc>()] as Foo>::bar()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `[Adt; _]`
-...
+ |
+note: required by `Foo::bar`
+ --> $DIR/dont-evaluate-array-len-on-err-1.rs:19:5
+ |
LL | fn bar() {}
- | -------- required by `Foo::bar`
+ | ^^^^^^^^
error: aborting due to previous error
error[E0277]: the trait bound `(): Foo<N>` is not satisfied
--> $DIR/exhaustive-value.rs:266:5
|
-LL | fn test() {}
- | --------- required by `Foo::test`
-...
LL | <() as Foo<N>>::test()
| ^^^^^^^^^^^^^^^^^^^^ the trait `Foo<N>` is not implemented for `()`
|
<() as Foo<101_u8>>
<() as Foo<102_u8>>
and 252 others
+note: required by `Foo::test`
+ --> $DIR/exhaustive-value.rs:6:5
+ |
+LL | fn test() {}
+ | ^^^^^^^^^
error: aborting due to previous error
error[E0277]: the trait bound `(): Foo<N>` is not satisfied
--> $DIR/exhaustive-value.rs:266:5
|
-LL | fn test() {}
- | --------- required by `Foo::test`
-...
LL | <() as Foo<N>>::test()
| ^^^^^^^^^^^^^^^^^^^^ the trait `Foo<N>` is not implemented for `()`
|
<() as Foo<101_u8>>
<() as Foo<102_u8>>
and 252 others
+note: required by `Foo::test`
+ --> $DIR/exhaustive-value.rs:6:5
+ |
+LL | fn test() {}
+ | ^^^^^^^^^
error: aborting due to previous error
error[E0277]: the trait bound `A<{_: usize}>: Bar<{_: usize}>` is not satisfied
--> $DIR/unused-substs-1.rs:12:13
|
-LL | / struct A<const N: usize>
-LL | | where
-LL | | A<N>: Bar<N>;
- | |_________________- required by `A`
-...
-LL | let _ = A;
- | ^ the trait `Bar<{_: usize}>` is not implemented for `A<{_: usize}>`
+LL | let _ = A;
+ | ^ the trait `Bar<{_: usize}>` is not implemented for `A<{_: usize}>`
|
= help: the following implementations were found:
<A<7_usize> as Bar<N>>
+note: required by `A`
+ --> $DIR/unused-substs-1.rs:7:1
+ |
+LL | / struct A<const N: usize>
+LL | | where
+LL | | A<N>: Bar<N>;
+ | |_________________^
error: aborting due to previous error
pub const UNDERFLOW: *const u16 = unsafe { [0u16; 1].as_ptr().offset(isize::MIN) }; //~NOTE
pub const OVERFLOW_ADDRESS_SPACE: *const u8 = unsafe { (usize::MAX as *const u8).offset(2) }; //~NOTE
pub const UNDERFLOW_ADDRESS_SPACE: *const u8 = unsafe { (1 as *const u8).offset(-2) }; //~NOTE
+pub const NEGATIVE_OFFSET: *const u8 = unsafe { [0u8; 1].as_ptr().wrapping_offset(-2).offset(-2) }; //~NOTE
pub const ZERO_SIZED_ALLOC: *const u8 = unsafe { [0u8; 0].as_ptr().offset(1) }; //~NOTE
pub const DANGLING: *const u8 = unsafe { ptr::NonNull::<u8>::dangling().as_ptr().offset(4) }; //~NOTE
LL | unsafe { intrinsics::offset(self, count) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
- | pointer arithmetic failed: allocN has size 0, so pointer to 1 bytes starting at offset 0 is out-of-bounds
+ | pointer arithmetic failed: allocN has size 1, so pointer to 2 bytes starting at offset -4 is out-of-bounds
| inside `ptr::const_ptr::<impl *const u8>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
- ::: $DIR/offset_ub.rs:17:50
+ ::: $DIR/offset_ub.rs:16:49
+ |
+LL | pub const NEGATIVE_OFFSET: *const u8 = unsafe { [0u8; 1].as_ptr().wrapping_offset(-2).offset(-2) };
+ | ------------------------------------------------ inside `NEGATIVE_OFFSET` at $DIR/offset_ub.rs:16:49
+
+error[E0080]: evaluation of constant value failed
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ |
+LL | unsafe { intrinsics::offset(self, count) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | pointer arithmetic failed: allocN has size 0, so pointer to 1 byte starting at offset 0 is out-of-bounds
+ | inside `ptr::const_ptr::<impl *const u8>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+ |
+ ::: $DIR/offset_ub.rs:18:50
|
LL | pub const ZERO_SIZED_ALLOC: *const u8 = unsafe { [0u8; 0].as_ptr().offset(1) };
- | --------------------------- inside `ZERO_SIZED_ALLOC` at $DIR/offset_ub.rs:17:50
+ | --------------------------- inside `ZERO_SIZED_ALLOC` at $DIR/offset_ub.rs:18:50
error[E0080]: evaluation of constant value failed
--> $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
| 0x1 is not a valid pointer
| inside `ptr::mut_ptr::<impl *mut u8>::offset` at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
|
- ::: $DIR/offset_ub.rs:18:42
+ ::: $DIR/offset_ub.rs:19:42
|
LL | pub const DANGLING: *const u8 = unsafe { ptr::NonNull::<u8>::dangling().as_ptr().offset(4) };
- | ------------------------------------------------- inside `DANGLING` at $DIR/offset_ub.rs:18:42
+ | ------------------------------------------------- inside `DANGLING` at $DIR/offset_ub.rs:19:42
error[E0080]: evaluation of constant value failed
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
| pointer arithmetic failed: 0x0 is not a valid pointer
| inside `ptr::const_ptr::<impl *const u8>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
- ::: $DIR/offset_ub.rs:21:50
+ ::: $DIR/offset_ub.rs:22:50
|
LL | pub const NULL_OFFSET_ZERO: *const u8 = unsafe { ptr::null::<u8>().offset(0) };
- | --------------------------- inside `NULL_OFFSET_ZERO` at $DIR/offset_ub.rs:21:50
+ | --------------------------- inside `NULL_OFFSET_ZERO` at $DIR/offset_ub.rs:22:50
error[E0080]: evaluation of constant value failed
--> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
| 0x7f..f is not a valid pointer
| inside `ptr::const_ptr::<impl *const u8>::offset` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
- ::: $DIR/offset_ub.rs:24:47
+ ::: $DIR/offset_ub.rs:25:47
|
LL | pub const UNDERFLOW_ABS: *const u8 = unsafe { (usize::MAX as *const u8).offset(isize::MIN) };
- | -------------------------------------------- inside `UNDERFLOW_ABS` at $DIR/offset_ub.rs:24:47
+ | -------------------------------------------- inside `UNDERFLOW_ABS` at $DIR/offset_ub.rs:25:47
-error: aborting due to 11 previous errors
+error: aborting due to 12 previous errors
For more information about this error, try `rustc --explain E0080`.
error[E0277]: the trait bound `TestDescAndFn: Testable` is not satisfied
--> $DIR/mismatch.rs:9:1
|
+LL | #[test]
+ | ------- in this procedural macro expansion
LL | fn wrong_kind(){}
| ^^^^^^^^^^^^^^^^^ the trait `Testable` is not implemented for `TestDescAndFn`
|
trait Foo {
#[derive(Clone)]
- //~^ ERROR `derive` may only be applied to structs, enums and unions
+ //~^ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s
type Bar;
}
impl Bar {
#[derive(Clone)]
- //~^ ERROR `derive` may only be applied to structs, enums and unions
+ //~^ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s
fn bar(&self) {}
}
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
--> $DIR/derive-on-trait-item-or-impl-item.rs:2:5
|
LL | #[derive(Clone)]
- | ^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^ not applicable here
+LL |
+LL | type Bar;
+ | --------- not a `struct`, `enum` or `union`
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
--> $DIR/derive-on-trait-item-or-impl-item.rs:10:5
|
LL | #[derive(Clone)]
- | ^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^ not applicable here
+LL |
+LL | fn bar(&self) {}
+ | ---------------- not a `struct`, `enum` or `union`
error: aborting due to 2 previous errors
error[E0277]: the trait bound `Error: Clone` is not satisfied
--> $DIR/derives-span-Clone-enum-struct-variant.rs:9:6
|
+LL | #[derive(Clone)]
+ | ----- in this derive macro expansion
+...
LL | x: Error
| ^^^^^^^^ the trait `Clone` is not implemented for `Error`
|
- = note: required by `clone`
+note: required by `clone`
+ --> $SRC_DIR/core/src/clone.rs:LL:COL
+ |
+LL | fn clone(&self) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
error[E0277]: the trait bound `Error: Clone` is not satisfied
--> $DIR/derives-span-Clone-enum.rs:9:6
|
+LL | #[derive(Clone)]
+ | ----- in this derive macro expansion
+...
LL | Error
| ^^^^^ the trait `Clone` is not implemented for `Error`
|
- = note: required by `clone`
+note: required by `clone`
+ --> $SRC_DIR/core/src/clone.rs:LL:COL
+ |
+LL | fn clone(&self) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
error[E0277]: the trait bound `Error: Clone` is not satisfied
--> $DIR/derives-span-Clone-struct.rs:8:5
|
+LL | #[derive(Clone)]
+ | ----- in this derive macro expansion
+LL | struct Struct {
LL | x: Error
| ^^^^^^^^ the trait `Clone` is not implemented for `Error`
|
- = note: required by `clone`
+note: required by `clone`
+ --> $SRC_DIR/core/src/clone.rs:LL:COL
+ |
+LL | fn clone(&self) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
error[E0277]: the trait bound `Error: Clone` is not satisfied
--> $DIR/derives-span-Clone-tuple-struct.rs:8:5
|
+LL | #[derive(Clone)]
+ | ----- in this derive macro expansion
+LL | struct Struct(
LL | Error
| ^^^^^ the trait `Clone` is not implemented for `Error`
|
- = note: required by `clone`
+note: required by `clone`
+ --> $SRC_DIR/core/src/clone.rs:LL:COL
+ |
+LL | fn clone(&self) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
error[E0277]: `Error` doesn't implement `Debug`
--> $DIR/derives-span-Debug-enum-struct-variant.rs:9:6
|
+LL | #[derive(Debug)]
+ | ----- in this derive macro expansion
+...
LL | x: Error
| ^^^^^^^^ `Error` cannot be formatted using `{:?}`
|
error[E0277]: `Error` doesn't implement `Debug`
--> $DIR/derives-span-Debug-enum.rs:9:6
|
+LL | #[derive(Debug)]
+ | ----- in this derive macro expansion
+...
LL | Error
| ^^^^^ `Error` cannot be formatted using `{:?}`
|
error[E0277]: `Error` doesn't implement `Debug`
--> $DIR/derives-span-Debug-struct.rs:8:5
|
+LL | #[derive(Debug)]
+ | ----- in this derive macro expansion
+LL | struct Struct {
LL | x: Error
| ^^^^^^^^ `Error` cannot be formatted using `{:?}`
|
error[E0277]: `Error` doesn't implement `Debug`
--> $DIR/derives-span-Debug-tuple-struct.rs:8:5
|
+LL | #[derive(Debug)]
+ | ----- in this derive macro expansion
+LL | struct Struct(
LL | Error
| ^^^^^ `Error` cannot be formatted using `{:?}`
|
error[E0277]: the trait bound `Error: Default` is not satisfied
--> $DIR/derives-span-Default-struct.rs:8:5
|
+LL | #[derive(Default)]
+ | ------- in this derive macro expansion
+LL | struct Struct {
LL | x: Error
| ^^^^^^^^ the trait `Default` is not implemented for `Error`
|
- = note: required by `std::default::Default::default`
+note: required by `std::default::Default::default`
+ --> $SRC_DIR/core/src/default.rs:LL:COL
+ |
+LL | fn default() -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
error[E0277]: the trait bound `Error: Default` is not satisfied
--> $DIR/derives-span-Default-tuple-struct.rs:8:5
|
+LL | #[derive(Default)]
+ | ------- in this derive macro expansion
+LL | struct Struct(
LL | Error
| ^^^^^ the trait `Default` is not implemented for `Error`
|
- = note: required by `std::default::Default::default`
+note: required by `std::default::Default::default`
+ --> $SRC_DIR/core/src/default.rs:LL:COL
+ |
+LL | fn default() -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
error[E0277]: the trait bound `Error: Eq` is not satisfied
--> $DIR/derives-span-Eq-enum-struct-variant.rs:9:6
|
+LL | #[derive(Eq,PartialEq)]
+ | -- in this derive macro expansion
+...
LL | x: Error
| ^^^^^^^^ the trait `Eq` is not implemented for `Error`
|
error[E0277]: the trait bound `Error: Eq` is not satisfied
--> $DIR/derives-span-Eq-enum.rs:9:6
|
+LL | #[derive(Eq,PartialEq)]
+ | -- in this derive macro expansion
+...
LL | Error
| ^^^^^ the trait `Eq` is not implemented for `Error`
|
error[E0277]: the trait bound `Error: Eq` is not satisfied
--> $DIR/derives-span-Eq-struct.rs:8:5
|
+LL | #[derive(Eq,PartialEq)]
+ | -- in this derive macro expansion
+LL | struct Struct {
LL | x: Error
| ^^^^^^^^ the trait `Eq` is not implemented for `Error`
|
error[E0277]: the trait bound `Error: Eq` is not satisfied
--> $DIR/derives-span-Eq-tuple-struct.rs:8:5
|
+LL | #[derive(Eq,PartialEq)]
+ | -- in this derive macro expansion
+LL | struct Struct(
LL | Error
| ^^^^^ the trait `Eq` is not implemented for `Error`
|
error[E0277]: the trait bound `Error: Hash` is not satisfied
--> $DIR/derives-span-Hash-enum-struct-variant.rs:9:6
|
+LL | #[derive(Hash)]
+ | ---- in this derive macro expansion
+...
LL | x: Error
| ^^^^^^^^ the trait `Hash` is not implemented for `Error`
|
error[E0277]: the trait bound `Error: Hash` is not satisfied
--> $DIR/derives-span-Hash-enum.rs:8:6
|
+LL | #[derive(Hash)]
+ | ---- in this derive macro expansion
+...
LL | Error
| ^^^^^ the trait `Hash` is not implemented for `Error`
|
error[E0277]: the trait bound `Error: Hash` is not satisfied
--> $DIR/derives-span-Hash-struct.rs:8:5
|
+LL | #[derive(Hash)]
+ | ---- in this derive macro expansion
+LL | struct Struct {
LL | x: Error
| ^^^^^^^^ the trait `Hash` is not implemented for `Error`
|
error[E0277]: the trait bound `Error: Hash` is not satisfied
--> $DIR/derives-span-Hash-tuple-struct.rs:8:5
|
+LL | #[derive(Hash)]
+ | ---- in this derive macro expansion
+LL | struct Struct(
LL | Error
| ^^^^^ the trait `Hash` is not implemented for `Error`
|
error[E0277]: the trait bound `Error: Ord` is not satisfied
--> $DIR/derives-span-Ord-enum-struct-variant.rs:9:6
|
+LL | #[derive(Ord,Eq,PartialOrd,PartialEq)]
+ | --- in this derive macro expansion
+...
LL | x: Error
| ^^^^^^^^ the trait `Ord` is not implemented for `Error`
|
- = note: required by `std::cmp::Ord::cmp`
+note: required by `std::cmp::Ord::cmp`
+ --> $SRC_DIR/core/src/cmp.rs:LL:COL
+ |
+LL | fn cmp(&self, other: &Self) -> Ordering;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
error[E0277]: the trait bound `Error: Ord` is not satisfied
--> $DIR/derives-span-Ord-enum.rs:9:6
|
+LL | #[derive(Ord,Eq,PartialOrd,PartialEq)]
+ | --- in this derive macro expansion
+...
LL | Error
| ^^^^^ the trait `Ord` is not implemented for `Error`
|
- = note: required by `std::cmp::Ord::cmp`
+note: required by `std::cmp::Ord::cmp`
+ --> $SRC_DIR/core/src/cmp.rs:LL:COL
+ |
+LL | fn cmp(&self, other: &Self) -> Ordering;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
error[E0277]: the trait bound `Error: Ord` is not satisfied
--> $DIR/derives-span-Ord-struct.rs:8:5
|
+LL | #[derive(Ord,Eq,PartialOrd,PartialEq)]
+ | --- in this derive macro expansion
+LL | struct Struct {
LL | x: Error
| ^^^^^^^^ the trait `Ord` is not implemented for `Error`
|
- = note: required by `std::cmp::Ord::cmp`
+note: required by `std::cmp::Ord::cmp`
+ --> $SRC_DIR/core/src/cmp.rs:LL:COL
+ |
+LL | fn cmp(&self, other: &Self) -> Ordering;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
error[E0277]: the trait bound `Error: Ord` is not satisfied
--> $DIR/derives-span-Ord-tuple-struct.rs:8:5
|
+LL | #[derive(Ord,Eq,PartialOrd,PartialEq)]
+ | --- in this derive macro expansion
+LL | struct Struct(
LL | Error
| ^^^^^ the trait `Ord` is not implemented for `Error`
|
- = note: required by `std::cmp::Ord::cmp`
+note: required by `std::cmp::Ord::cmp`
+ --> $SRC_DIR/core/src/cmp.rs:LL:COL
+ |
+LL | fn cmp(&self, other: &Self) -> Ordering;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
error[E0369]: binary operation `==` cannot be applied to type `Error`
--> $DIR/derives-span-PartialEq-enum-struct-variant.rs:9:6
|
+LL | #[derive(PartialEq)]
+ | --------- in this derive macro expansion
+...
LL | x: Error
| ^^^^^^^^
|
error[E0369]: binary operation `!=` cannot be applied to type `Error`
--> $DIR/derives-span-PartialEq-enum-struct-variant.rs:9:6
|
+LL | #[derive(PartialEq)]
+ | --------- in this derive macro expansion
+...
LL | x: Error
| ^^^^^^^^
|
error[E0369]: binary operation `==` cannot be applied to type `Error`
--> $DIR/derives-span-PartialEq-enum.rs:9:6
|
+LL | #[derive(PartialEq)]
+ | --------- in this derive macro expansion
+...
LL | Error
| ^^^^^
|
error[E0369]: binary operation `!=` cannot be applied to type `Error`
--> $DIR/derives-span-PartialEq-enum.rs:9:6
|
+LL | #[derive(PartialEq)]
+ | --------- in this derive macro expansion
+...
LL | Error
| ^^^^^
|
error[E0369]: binary operation `==` cannot be applied to type `Error`
--> $DIR/derives-span-PartialEq-struct.rs:8:5
|
+LL | #[derive(PartialEq)]
+ | --------- in this derive macro expansion
+LL | struct Struct {
LL | x: Error
| ^^^^^^^^
|
error[E0369]: binary operation `!=` cannot be applied to type `Error`
--> $DIR/derives-span-PartialEq-struct.rs:8:5
|
+LL | #[derive(PartialEq)]
+ | --------- in this derive macro expansion
+LL | struct Struct {
LL | x: Error
| ^^^^^^^^
|
error[E0369]: binary operation `==` cannot be applied to type `Error`
--> $DIR/derives-span-PartialEq-tuple-struct.rs:8:5
|
+LL | #[derive(PartialEq)]
+ | --------- in this derive macro expansion
+LL | struct Struct(
LL | Error
| ^^^^^
|
error[E0369]: binary operation `!=` cannot be applied to type `Error`
--> $DIR/derives-span-PartialEq-tuple-struct.rs:8:5
|
+LL | #[derive(PartialEq)]
+ | --------- in this derive macro expansion
+LL | struct Struct(
LL | Error
| ^^^^^
|
error[E0277]: can't compare `Error` with `Error`
--> $DIR/derives-span-PartialOrd-enum-struct-variant.rs:9:6
|
+LL | #[derive(PartialOrd,PartialEq)]
+ | ---------- in this derive macro expansion
+...
LL | x: Error
| ^^^^^^^^ no implementation for `Error < Error` and `Error > Error`
|
= help: the trait `PartialOrd` is not implemented for `Error`
- = note: required by `std::cmp::PartialOrd::partial_cmp`
+note: required by `std::cmp::PartialOrd::partial_cmp`
+ --> $SRC_DIR/core/src/cmp.rs:LL:COL
+ |
+LL | fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
error[E0277]: can't compare `Error` with `Error`
--> $DIR/derives-span-PartialOrd-enum.rs:9:6
|
+LL | #[derive(PartialOrd,PartialEq)]
+ | ---------- in this derive macro expansion
+...
LL | Error
| ^^^^^ no implementation for `Error < Error` and `Error > Error`
|
= help: the trait `PartialOrd` is not implemented for `Error`
- = note: required by `std::cmp::PartialOrd::partial_cmp`
+note: required by `std::cmp::PartialOrd::partial_cmp`
+ --> $SRC_DIR/core/src/cmp.rs:LL:COL
+ |
+LL | fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
error[E0277]: can't compare `Error` with `Error`
--> $DIR/derives-span-PartialOrd-struct.rs:8:5
|
+LL | #[derive(PartialOrd,PartialEq)]
+ | ---------- in this derive macro expansion
+LL | struct Struct {
LL | x: Error
| ^^^^^^^^ no implementation for `Error < Error` and `Error > Error`
|
= help: the trait `PartialOrd` is not implemented for `Error`
- = note: required by `std::cmp::PartialOrd::partial_cmp`
+note: required by `std::cmp::PartialOrd::partial_cmp`
+ --> $SRC_DIR/core/src/cmp.rs:LL:COL
+ |
+LL | fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
error[E0277]: can't compare `Error` with `Error`
--> $DIR/derives-span-PartialOrd-tuple-struct.rs:8:5
|
+LL | #[derive(PartialOrd,PartialEq)]
+ | ---------- in this derive macro expansion
+LL | struct Struct(
LL | Error
| ^^^^^ no implementation for `Error < Error` and `Error > Error`
|
= help: the trait `PartialOrd` is not implemented for `Error`
- = note: required by `std::cmp::PartialOrd::partial_cmp`
+note: required by `std::cmp::PartialOrd::partial_cmp`
+ --> $SRC_DIR/core/src/cmp.rs:LL:COL
+ |
+LL | fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
| expected an implementor of trait `Copy`
| help: consider borrowing here: `&B { a: 1, b: C }`
|
- = note: required because of the requirements on the impl of `Copy` for `B<C>`
+note: required because of the requirements on the impl of `Copy` for `B<C>`
+ --> $DIR/deriving-copyclone.rs:9:10
+ |
+LL | #[derive(Copy, Clone)]
+ | ^^^^
+ = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `C: Clone` is not satisfied
--> $DIR/deriving-copyclone.rs:32:14
| expected an implementor of trait `Clone`
| help: consider borrowing here: `&B { a: 1, b: C }`
|
- = note: required because of the requirements on the impl of `Clone` for `B<C>`
+note: required because of the requirements on the impl of `Clone` for `B<C>`
+ --> $DIR/deriving-copyclone.rs:9:16
+ |
+LL | #[derive(Copy, Clone)]
+ | ^^^^^
+ = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `D: Copy` is not satisfied
--> $DIR/deriving-copyclone.rs:35:13
| expected an implementor of trait `Copy`
| help: consider borrowing here: `&B { a: 1, b: D }`
|
- = note: required because of the requirements on the impl of `Copy` for `B<D>`
+note: required because of the requirements on the impl of `Copy` for `B<D>`
+ --> $DIR/deriving-copyclone.rs:9:10
+ |
+LL | #[derive(Copy, Clone)]
+ | ^^^^
+ = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 3 previous errors
error[E0369]: binary operation `==` cannot be applied to type `NoCloneOrEq`
--> $DIR/deriving-no-inner-impl-error-message.rs:5:5
|
+LL | #[derive(PartialEq)]
+ | --------- in this derive macro expansion
+LL | struct E {
LL | x: NoCloneOrEq
| ^^^^^^^^^^^^^^
|
error[E0369]: binary operation `!=` cannot be applied to type `NoCloneOrEq`
--> $DIR/deriving-no-inner-impl-error-message.rs:5:5
|
+LL | #[derive(PartialEq)]
+ | --------- in this derive macro expansion
+LL | struct E {
LL | x: NoCloneOrEq
| ^^^^^^^^^^^^^^
|
error[E0277]: the trait bound `NoCloneOrEq: Clone` is not satisfied
--> $DIR/deriving-no-inner-impl-error-message.rs:10:5
|
+LL | #[derive(Clone)]
+ | ----- in this derive macro expansion
+LL | struct C {
LL | x: NoCloneOrEq
| ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `NoCloneOrEq`
|
- = note: required by `clone`
+note: required by `clone`
+ --> $SRC_DIR/core/src/clone.rs:LL:COL
+ |
+LL | fn clone(&self) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 3 previous errors
struct S;
-#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs, enums and unions
+#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to `struct`s, `enum`s and `union`s
trait T { }
-#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs, enums and unions
+#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to `struct`s, `enum`s and `union`s
impl S { }
-#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs, enums and unions
+#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to `struct`s, `enum`s and `union`s
impl T for S { }
-#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs, enums and unions
+#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to `struct`s, `enum`s and `union`s
static s: usize = 0;
-#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs, enums and unions
+#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to `struct`s, `enum`s and `union`s
const c: usize = 0;
-#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs, enums and unions
+#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to `struct`s, `enum`s and `union`s
mod m { }
-#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs, enums and unions
+#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to `struct`s, `enum`s and `union`s
extern "C" { }
-#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs, enums and unions
+#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to `struct`s, `enum`s and `union`s
type A = usize;
-#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs, enums and unions
+#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to `struct`s, `enum`s and `union`s
fn main() { }
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
--> $DIR/deriving-non-type.rs:5:1
|
LL | #[derive(PartialEq)]
- | ^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^ not applicable here
+LL | trait T { }
+ | ----------- not a `struct`, `enum` or `union`
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
--> $DIR/deriving-non-type.rs:8:1
|
LL | #[derive(PartialEq)]
- | ^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^ not applicable here
+LL | impl S { }
+ | ---------- not a `struct`, `enum` or `union`
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
--> $DIR/deriving-non-type.rs:11:1
|
LL | #[derive(PartialEq)]
- | ^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^ not applicable here
+LL | impl T for S { }
+ | ---------------- not a `struct`, `enum` or `union`
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
--> $DIR/deriving-non-type.rs:14:1
|
LL | #[derive(PartialEq)]
- | ^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^ not applicable here
+LL | static s: usize = 0;
+ | -------------------- not a `struct`, `enum` or `union`
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
--> $DIR/deriving-non-type.rs:17:1
|
LL | #[derive(PartialEq)]
- | ^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^ not applicable here
+LL | const c: usize = 0;
+ | ------------------- not a `struct`, `enum` or `union`
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
--> $DIR/deriving-non-type.rs:20:1
|
LL | #[derive(PartialEq)]
- | ^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^ not applicable here
+LL | mod m { }
+ | --------- not a `struct`, `enum` or `union`
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
--> $DIR/deriving-non-type.rs:23:1
|
LL | #[derive(PartialEq)]
- | ^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^ not applicable here
+LL | extern "C" { }
+ | -------------- not a `struct`, `enum` or `union`
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
--> $DIR/deriving-non-type.rs:26:1
|
LL | #[derive(PartialEq)]
- | ^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^ not applicable here
+LL | type A = usize;
+ | --------------- not a `struct`, `enum` or `union`
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
--> $DIR/deriving-non-type.rs:29:1
|
LL | #[derive(PartialEq)]
- | ^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^ not applicable here
+LL | fn main() { }
+ | ------------- not a `struct`, `enum` or `union`
error: aborting due to 9 previous errors
error[E0277]: the trait bound `i8: Foo<i32>` is not satisfied
--> $DIR/issue-39802-show-5-trait-impls.rs:24:21
|
-LL | fn bar(&self){}
- | ------------- required by `Foo::bar`
-...
LL | Foo::<i32>::bar(&1i8);
| ^^^^ the trait `Foo<i32>` is not implemented for `i8`
|
<i8 as Foo<u32>>
<i8 as Foo<u64>>
<i8 as Foo<u8>>
+note: required by `Foo::bar`
+ --> $DIR/issue-39802-show-5-trait-impls.rs:2:5
+ |
+LL | fn bar(&self){}
+ | ^^^^^^^^^^^^^
error[E0277]: the trait bound `u8: Foo<i32>` is not satisfied
--> $DIR/issue-39802-show-5-trait-impls.rs:25:21
|
-LL | fn bar(&self){}
- | ------------- required by `Foo::bar`
-...
LL | Foo::<i32>::bar(&1u8);
| ^^^^ the trait `Foo<i32>` is not implemented for `u8`
|
<u8 as Foo<u16>>
<u8 as Foo<u32>>
<u8 as Foo<u64>>
+note: required by `Foo::bar`
+ --> $DIR/issue-39802-show-5-trait-impls.rs:2:5
+ |
+LL | fn bar(&self){}
+ | ^^^^^^^^^^^^^
error[E0277]: the trait bound `bool: Foo<i32>` is not satisfied
--> $DIR/issue-39802-show-5-trait-impls.rs:26:21
|
-LL | fn bar(&self){}
- | ------------- required by `Foo::bar`
-...
LL | Foo::<i32>::bar(&true);
| ^^^^^ the trait `Foo<i32>` is not implemented for `bool`
|
<bool as Foo<u16>>
<bool as Foo<u32>>
and 2 others
+note: required by `Foo::bar`
+ --> $DIR/issue-39802-show-5-trait-impls.rs:2:5
+ |
+LL | fn bar(&self){}
+ | ^^^^^^^^^^^^^
error: aborting due to 3 previous errors
#![feature(imported_main)]
-#![feature(min_type_alias_impl_trait, impl_trait_in_bindings)]
+#![feature(min_type_alias_impl_trait)]
#![allow(incomplete_features)]
//~^^^ ERROR `main` function not found in crate
pub mod foo {
type MainFn = impl Fn();
+ //~^ ERROR could not find defining uses
fn bar() {}
pub const BAR: MainFn = bar;
+ //~^ ERROR mismatched types [E0308]
}
use foo::BAR as main;
--> $DIR/imported_main_const_fn_item_type_forbidden.rs:1:1
|
LL | / #![feature(imported_main)]
-LL | | #![feature(min_type_alias_impl_trait, impl_trait_in_bindings)]
+LL | | #![feature(min_type_alias_impl_trait)]
LL | | #![allow(incomplete_features)]
LL | |
... |
| |
| non-function item at `crate::main` is found
-error: aborting due to previous error
+error[E0308]: mismatched types
+ --> $DIR/imported_main_const_fn_item_type_forbidden.rs:10:29
+ |
+LL | type MainFn = impl Fn();
+ | --------- the expected opaque type
+...
+LL | pub const BAR: MainFn = bar;
+ | ^^^ expected opaque type, found fn item
+ |
+ = note: expected opaque type `impl Fn<()>`
+ found fn item `fn() {bar}`
+
+error: could not find defining uses
+ --> $DIR/imported_main_const_fn_item_type_forbidden.rs:6:19
+ |
+LL | type MainFn = impl Fn();
+ | ^^^^^^^^^
+
+error: aborting due to 3 previous errors
-For more information about this error, try `rustc --explain E0601`.
+Some errors have detailed explanations: E0308, E0601.
+For more information about an error, try `rustc --explain E0308`.
error[E0038]: the trait `Trait` cannot be made into an object
- --> $DIR/E0038.rs:5:16
+ --> $DIR/E0038.rs:5:20
|
LL | fn call_foo(x: Box<dyn Trait>) {
- | ^^^^^^^^^^^^^^ `Trait` cannot be made into an object
+ | ^^^^^^^^^ `Trait` cannot be made into an object
|
= help: consider moving `foo` to another trait
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>
error[E0283]: type annotations needed
--> $DIR/E0283.rs:30:21
|
-LL | fn create() -> u32;
- | ------------------- required by `Generator::create`
-...
LL | let cont: u32 = Generator::create();
| ^^^^^^^^^^^^^^^^^ cannot infer type
|
= note: cannot satisfy `_: Generator`
+note: required by `Generator::create`
+ --> $DIR/E0283.rs:2:5
+ |
+LL | fn create() -> u32;
+ | ^^^^^^^^^^^^^^^^^^^
error[E0283]: type annotations needed
--> $DIR/E0283.rs:35:24
error[E0624]: associated function `method` is private
--> $DIR/E0624.rs:11:9
|
+LL | fn method(&self) {}
+ | ---------------- private associated function defined here
+...
LL | foo.method();
| ^^^^^^ private associated function
--> $DIR/E0777.rs:1:10
|
LL | #[derive("Clone")]
- | ^^^^^^^
+ | ^^^^^^^ not a trait
|
= help: try using `#[derive(Clone)]`
LL | #[derive("Clone
| __________^
LL | | ")]
- | |_^
+ | |_^ not a trait
|
= help: for example, write `#[derive(Debug)]` for `Debug`
|
LL | r.pub_crate();
| ^^^^^^^^^ private associated function
+ |
+ ::: $DIR/auxiliary/pub-and-stability.rs:114:9
+ |
+LL | pub(crate) fn pub_crate(&self) -> i32 { self.d_priv }
+ | ------------------------------------- private associated function defined here
error[E0624]: associated function `pub_mod` is private
--> $DIR/explore-issue-38412.rs:51:7
|
LL | r.pub_mod();
| ^^^^^^^ private associated function
+ |
+ ::: $DIR/auxiliary/pub-and-stability.rs:116:9
+ |
+LL | pub(in m) fn pub_mod(&self) -> i32 { self.d_priv }
+ | ---------------------------------- private associated function defined here
error[E0624]: associated function `private` is private
--> $DIR/explore-issue-38412.rs:52:7
|
LL | r.private();
| ^^^^^^^ private associated function
+ |
+ ::: $DIR/auxiliary/pub-and-stability.rs:118:9
+ |
+LL | fn private(&self) -> i32 { self.d_priv }
+ | ------------------------ private associated function defined here
error[E0658]: use of unstable library feature 'unstable_undeclared'
--> $DIR/explore-issue-38412.rs:57:7
|
LL | t.pub_crate();
| ^^^^^^^^^ private associated function
+ |
+ ::: $DIR/auxiliary/pub-and-stability.rs:129:9
+ |
+LL | pub(crate) fn pub_crate(&self) -> i32 { self.0 }
+ | ------------------------------------- private associated function defined here
error[E0624]: associated function `pub_mod` is private
--> $DIR/explore-issue-38412.rs:64:7
|
LL | t.pub_mod();
| ^^^^^^^ private associated function
+ |
+ ::: $DIR/auxiliary/pub-and-stability.rs:130:9
+ |
+LL | pub(in m) fn pub_mod(&self) -> i32 { self.0 }
+ | ---------------------------------- private associated function defined here
error[E0624]: associated function `private` is private
--> $DIR/explore-issue-38412.rs:65:7
|
LL | t.private();
| ^^^^^^^ private associated function
+ |
+ ::: $DIR/auxiliary/pub-and-stability.rs:131:9
+ |
+LL | fn private(&self) -> i32 { self.0 }
+ | ------------------------ private associated function defined here
error: aborting due to 19 previous errors
const _cdef: impl Tr1<As1: Copy> = S1;
//~^ ERROR associated type bounds are unstable
-//~| ERROR `impl Trait` not allowed outside of function and inherent method return types [E0562]
+//~| ERROR `impl Trait` not allowed outside of function and method return types [E0562]
// FIXME: uncomment when `impl_trait_in_bindings` feature is fixed.
// const _cdef_dyn: &dyn Tr1<As1: Copy> = &S1;
static _sdef: impl Tr1<As1: Copy> = S1;
//~^ ERROR associated type bounds are unstable
-//~| ERROR `impl Trait` not allowed outside of function and inherent method return types [E0562]
+//~| ERROR `impl Trait` not allowed outside of function and method return types [E0562]
// FIXME: uncomment when `impl_trait_in_bindings` feature is fixed.
// static _sdef_dyn: &dyn Tr1<As1: Copy> = &S1;
fn main() {
let _: impl Tr1<As1: Copy> = S1;
//~^ ERROR associated type bounds are unstable
- //~| ERROR `impl Trait` not allowed outside of function and inherent method return types [E0562]
+ //~| ERROR `impl Trait` not allowed outside of function and method return types [E0562]
// FIXME: uncomment when `impl_trait_in_bindings` feature is fixed.
// let _: &dyn Tr1<As1: Copy> = &S1;
}
= note: see issue #52662 <https://github.com/rust-lang/rust/issues/52662> for more information
= help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/feature-gate-associated_type_bounds.rs:58:14
|
LL | const _cdef: impl Tr1<As1: Copy> = S1;
| ^^^^^^^^^^^^^^^^^^^
- |
- = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/feature-gate-associated_type_bounds.rs:64:15
|
LL | static _sdef: impl Tr1<As1: Copy> = S1;
| ^^^^^^^^^^^^^^^^^^^
- |
- = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/feature-gate-associated_type_bounds.rs:71:12
|
LL | let _: impl Tr1<As1: Copy> = S1;
| ^^^^^^^^^^^^^^^^^^^
- |
- = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
error[E0277]: the trait bound `<<Self as _Tr3>::A as Iterator>::Item: Copy` is not satisfied
--> $DIR/feature-gate-associated_type_bounds.rs:15:28
+++ /dev/null
-const FOO: impl Copy = 42;
-//~^ ERROR `impl Trait` not allowed
-
-static BAR: impl Copy = 42;
-//~^ ERROR `impl Trait` not allowed
-
-fn main() {
- let foo = impl Copy = 42;
-//~^ ERROR expected expression, found keyword `impl`
- let foo: impl Copy = 42;
-}
+++ /dev/null
-error: expected expression, found keyword `impl`
- --> $DIR/feature-gate-impl_trait_in_bindings.rs:8:15
- |
-LL | let foo = impl Copy = 42;
- | ^^^^ expected expression
-
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
- --> $DIR/feature-gate-impl_trait_in_bindings.rs:1:12
- |
-LL | const FOO: impl Copy = 42;
- | ^^^^^^^^^
- |
- = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
-
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
- --> $DIR/feature-gate-impl_trait_in_bindings.rs:4:13
- |
-LL | static BAR: impl Copy = 42;
- | ^^^^^^^^^
- |
- = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0562`.
= note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
= help: add `#![feature(min_type_alias_impl_trait)]` to the crate attributes to enable
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/feature-gate-min_type_alias_impl_trait.rs:23:18
|
LL | type Assoc = impl Debug;
error[E0038]: the trait `NonObjectSafe1` cannot be made into an object
- --> $DIR/feature-gate-object_safe_for_dispatch.rs:18:38
+ --> $DIR/feature-gate-object_safe_for_dispatch.rs:18:39
|
LL | fn takes_non_object_safe_ref<T>(obj: &dyn NonObjectSafe1) {
- | ^^^^^^^^^^^^^^^^^^^ `NonObjectSafe1` cannot be made into an object
+ | ^^^^^^^^^^^^^^^^^^ `NonObjectSafe1` 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/feature-gate-object_safe_for_dispatch.rs:4:23
| ^^^^^^^^^^^^^^^^^
error[E0038]: the trait `NonObjectSafe3` cannot be made into an object
- --> $DIR/feature-gate-object_safe_for_dispatch.rs:27:35
+ --> $DIR/feature-gate-object_safe_for_dispatch.rs:27:39
|
LL | fn takes_non_object_safe_box(obj: Box<dyn NonObjectSafe3>) {
- | ^^^^^^^^^^^^^^^^^^^^^^^ `NonObjectSafe3` cannot be made into an object
+ | ^^^^^^^^^^^^^^^^^^ `NonObjectSafe3` cannot be made into an object
|
= help: consider moving `foo` to another trait
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>
error: aborting due to 6 previous errors
-For more information about this error, try `rustc --explain E0658`.
+Some errors have detailed explanations: E0658, E0722.
+For more information about an error, try `rustc --explain E0658`.
fn define4() {
let y: Foo4 = 42;
- //~^ ERROR not permitted here
+ //~^ ERROR mismatched types [E0308]
}
fn main() {}
= note: expected opaque type `impl Debug`
found type `{integer}`
-error[E0658]: type alias impl trait is not permitted here
- --> $DIR/feature-gate-type_alias_impl_trait.rs:33:12
+error[E0308]: mismatched types
+ --> $DIR/feature-gate-type_alias_impl_trait.rs:33:19
|
+LL | type Foo4 = impl Debug;
+ | ---------- the expected opaque type
+...
LL | let y: Foo4 = 42;
- | ^^^^
+ | ---- ^^ expected opaque type, found integer
+ | |
+ | expected due to this
|
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
- = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
+ = note: expected opaque type `impl Debug`
+ found type `{integer}`
error: could not find defining uses
--> $DIR/feature-gate-type_alias_impl_trait.rs:5:12
// definitions.
#[derive(Debug)]
-//~^ ERROR `derive` may only be applied to structs, enums and unions
+//~^ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s
mod derive {
mod inner { #![derive(Debug)] }
- //~^ ERROR `derive` may only be applied to structs, enums and unions
+ //~^ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s
//~| ERROR inner macro attributes are unstable
#[derive(Debug)]
- //~^ ERROR `derive` may only be applied to structs, enums and unions
+ //~^ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s
fn derive() { }
#[derive(Copy, Clone)] // (can't derive Debug for unions)
enum E { }
#[derive(Debug)]
- //~^ ERROR `derive` may only be applied to structs, enums and unions
+ //~^ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s
type T = S;
#[derive(Debug)]
- //~^ ERROR `derive` may only be applied to structs, enums and unions
+ //~^ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s
impl S { }
}
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
--> $DIR/issue-43106-gating-of-derive.rs:4:1
|
-LL | #[derive(Debug)]
- | ^^^^^^^^^^^^^^^^
+LL | #[derive(Debug)]
+ | ^^^^^^^^^^^^^^^^ not applicable here
+LL |
+LL | / mod derive {
+LL | | mod inner { #![derive(Debug)] }
+LL | |
+LL | |
+... |
+LL | | impl S { }
+LL | | }
+ | |_- not a `struct`, `enum` or `union`
error[E0658]: inner macro attributes are unstable
--> $DIR/issue-43106-gating-of-derive.rs:7:20
= note: see issue #54726 <https://github.com/rust-lang/rust/issues/54726> for more information
= help: add `#![feature(custom_inner_attributes)]` to the crate attributes to enable
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
--> $DIR/issue-43106-gating-of-derive.rs:7:17
|
LL | mod inner { #![derive(Debug)] }
- | ^^^^^^^^^^^^^^^^^
+ | ------------^^^^^^^^^^^^^^^^^--
+ | | |
+ | | not applicable here
+ | not a `struct`, `enum` or `union`
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
--> $DIR/issue-43106-gating-of-derive.rs:11:5
|
LL | #[derive(Debug)]
- | ^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^ not applicable here
+LL |
+LL | fn derive() { }
+ | --------------- not a `struct`, `enum` or `union`
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
--> $DIR/issue-43106-gating-of-derive.rs:24:5
|
LL | #[derive(Debug)]
- | ^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^ not applicable here
+LL |
+LL | type T = S;
+ | ----------- not a `struct`, `enum` or `union`
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
--> $DIR/issue-43106-gating-of-derive.rs:28:5
|
LL | #[derive(Debug)]
- | ^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^ not applicable here
+LL |
+LL | impl S { }
+ | ---------- not a `struct`, `enum` or `union`
error: aborting due to 6 previous errors
error: aborting due to previous error
+For more information about this error, try `rustc --explain E0757`.
| ^^^ the trait `UpperHex` is not implemented for `str`
|
= note: required because of the requirements on the impl of `UpperHex` for `&str`
- = note: required by `std::fmt::UpperHex::fmt`
+note: required by `std::fmt::UpperHex::fmt`
+ --> $SRC_DIR/core/src/fmt/mod.rs:LL:COL
+ |
+LL | fn fmt(&self, f: &mut Formatter<'_>) -> Result;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the macro `$crate::__export::format_args` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
|
= help: the trait `Iterator` is not implemented for `&str`
= note: required because of the requirements on the impl of `IntoIterator` for `&str`
- = note: required by `into_iter`
+note: required by `into_iter`
+ --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+ |
+LL | fn into_iter(self) -> Self::IntoIter;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
|
= help: the trait `Iterator` is not implemented for `MyStruct`
= note: required because of the requirements on the impl of `IntoIterator` for `MyStruct`
- = note: required by `into_iter`
+note: required by `into_iter`
+ --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+ |
+LL | fn into_iter(self) -> Self::IntoIter;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
error[E0425]: cannot find value `Foo` in this scope
- --> $DIR/layout-error.rs:25:17
+ --> $DIR/layout-error.rs:24:17
|
LL | let a = Foo;
| ^^^ not found in this scope
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
+warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/layout-error.rs:8:32
|
-LL | #![cfg_attr(full_tait, feature(impl_trait_in_bindings, type_alias_impl_trait))]
- | ^^^^^^^^^^^^^^^^^^^^^^
+LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))]
+ | ^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
-warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/layout-error.rs:8:56
- |
-LL | #![cfg_attr(full_tait, feature(impl_trait_in_bindings, type_alias_impl_trait))]
- | ^^^^^^^^^^^^^^^^^^^^^
- |
= note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
-error: aborting due to previous error; 2 warnings emitted
+error: aborting due to previous error; 1 warning emitted
For more information about this error, try `rustc --explain E0425`.
error[E0425]: cannot find value `Foo` in this scope
- --> $DIR/layout-error.rs:25:17
+ --> $DIR/layout-error.rs:24:17
|
LL | let a = Foo;
| ^^^ not found in this scope
error[E0658]: type alias impl trait is not permitted here
- --> $DIR/layout-error.rs:31:27
+ --> $DIR/layout-error.rs:30:27
|
LL | Task::spawn(&POOL, || cb());
| ^
= note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
= help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
-error[E0658]: type alias impl trait is not permitted here
- --> $DIR/layout-error.rs:30:28
- |
-LL | static POOL: Task<F> = Task::new();
- | ^^^^^^^^^^^
- |
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
- = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
-
-error: concrete type differs from previous defining opaque type use
- --> $DIR/layout-error.rs:31:24
- |
-LL | Task::spawn(&POOL, || cb());
- | ^^^^^^^ expected `[type error]`, got `impl Future`
- |
-note: previous use here
- --> $DIR/layout-error.rs:30:5
- |
-LL | static POOL: Task<F> = Task::new();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
Some errors have detailed explanations: E0425, E0658.
For more information about an error, try `rustc --explain E0425`.
// revisions: min_tait full_tait
#![feature(min_type_alias_impl_trait)]
-#![cfg_attr(full_tait, feature(impl_trait_in_bindings, type_alias_impl_trait))]
+#![cfg_attr(full_tait, feature(type_alias_impl_trait))]
//[full_tait]~^ WARN incomplete
-//[full_tait]~| WARN incomplete
use std::future::Future;
pub struct Task<F: Future>(F);
type F = impl Future;
// Check that statics are inhabited computes they layout.
- static POOL: Task<F> = Task::new(); //[min_tait]~ ERROR not permitted here
+ static POOL: Task<F> = Task::new();
Task::spawn(&POOL, || cb()); //[min_tait]~ ERROR type alias impl trait is not permitted here
- //[min_tait]~^ ERROR concrete type differs from previous
}
warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/metadata-sufficient-for-layout.rs:10:32
|
-LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
+LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))]
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/metadata-sufficient-for-layout.rs:10:55
- |
-LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
- | ^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
error: fatal error triggered by #[rustc_error]
- --> $DIR/metadata-sufficient-for-layout.rs:29:1
+ --> $DIR/metadata-sufficient-for-layout.rs:28:1
|
LL | fn main() {}
| ^^^^^^^^^
-error: aborting due to previous error; 2 warnings emitted
+error: aborting due to previous error; 1 warning emitted
-error[E0658]: type alias impl trait is not permitted here
- --> $DIR/metadata-sufficient-for-layout.rs:22:23
+error: fatal error triggered by #[rustc_error]
+ --> $DIR/metadata-sufficient-for-layout.rs:28:1
|
-LL | static A: Option<F> = None;
- | ^^^^
- |
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
- = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
-
-error: concrete type differs from previous defining opaque type use
- --> $DIR/metadata-sufficient-for-layout.rs:25:1
- |
-LL | fn f() -> F { metadata_sufficient_for_layout::g() }
- | ^^^^^^^^^^^ expected `[type error]`, got `impl Generator`
- |
-note: previous use here
- --> $DIR/metadata-sufficient-for-layout.rs:22:1
- |
-LL | static A: Option<F> = None;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | fn main() {}
+ | ^^^^^^^^^
-error: aborting due to 2 previous errors
+error: aborting due to previous error
-For more information about this error, try `rustc --explain E0658`.
// revisions: min_tait full_tait
#![feature(min_type_alias_impl_trait, rustc_attrs)]
-#![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
+#![cfg_attr(full_tait, feature(type_alias_impl_trait))]
//[full_tait]~^ WARN incomplete
-//[full_tait]~| WARN incomplete
#![feature(generator_trait)]
extern crate metadata_sufficient_for_layout;
// Static queries the layout of the generator.
static A: Option<F> = None;
-//[min_tait]~^ ERROR not permitted here
-fn f() -> F { metadata_sufficient_for_layout::g() }
-//[min_tait]~^ ERROR concrete type differs
+fn f() -> F {
+ metadata_sufficient_for_layout::g()
+}
#[rustc_error]
-fn main() {} //[full_tait]~ ERROR
+fn main() {} //~ ERROR
= help: the trait `Iterator` is not implemented for `{integer}`
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
= note: required because of the requirements on the impl of `IntoIterator` for `{integer}`
- = note: required by `into_iter`
+note: required by `into_iter`
+ --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+ |
+LL | fn into_iter(self) -> Self::IntoIter;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
error[E0038]: the trait `Foo` cannot be made into an object
- --> $DIR/gat-in-trait-path.rs:21:13
+ --> $DIR/gat-in-trait-path.rs:21:17
|
LL | fn f(_arg : Box<dyn for<'a> Foo<A<'a> = &'a ()>>) {}
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object
|
= help: consider moving `A` to another trait
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>
LL | type C where Self: Copy = String;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
|
- = note: required because of the requirements on the impl of `Copy` for `Fooy<T>`
+note: required because of the requirements on the impl of `Copy` for `Fooy<T>`
+ --> $DIR/impl_bounds.rs:11:10
+ |
+LL | #[derive(Copy, Clone)]
+ | ^^^^
note: the requirement `Fooy<T>: Copy` appears on the associated impl type `C` but not on the corresponding associated trait type
--> $DIR/impl_bounds.rs:7:5
|
...
LL | type C where Self: Clone;
| ^^^^^^^^^^^^^^^^^^^^^^^^^ this trait associated type doesn't have the requirement `Fooy<T>: Copy`
+ = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider restricting type parameter `T`
|
LL | impl<T: std::marker::Copy> Foo for Fooy<T> {
LL | fn d() where Self: Copy {}
| ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
|
- = note: required because of the requirements on the impl of `Copy` for `Fooy<T>`
+note: required because of the requirements on the impl of `Copy` for `Fooy<T>`
+ --> $DIR/impl_bounds.rs:11:10
+ |
+LL | #[derive(Copy, Clone)]
+ | ^^^^
note: the requirement `Fooy<T>: Copy` appears on the impl method `d` but not on the corresponding trait method
--> $DIR/impl_bounds.rs:8:8
|
...
LL | fn d() where Self: Clone;
| ^ this trait method doesn't have the requirement `Fooy<T>: Copy`
+ = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider restricting type parameter `T`
|
LL | impl<T: std::marker::Copy> Foo for Fooy<T> {
error[E0038]: the trait `X` cannot be made into an object
- --> $DIR/issue-67510-pass.rs:7:19
+ --> $DIR/issue-67510-pass.rs:7:23
|
LL | fn _func1<'a>(_x: Box<dyn X<Y<'a>=&'a ()>>) {}
- | ^^^^^^^^^^^^^^^^^^^^^^^^ `X` cannot be made into an object
+ | ^^^^^^^^^^^^^^^^^^^ `X` cannot be made into an object
|
= help: consider moving `Y` to another trait
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>
--- /dev/null
+// Test for diagnostics when we have mismatched lifetime due to implict 'static lifetime in GATs
+
+// check-fail
+
+#![feature(generic_associated_types)]
+
+pub trait A {}
+impl A for &dyn A {}
+impl A for Box<dyn A> {}
+
+pub trait B {
+ type T<'a>: A;
+}
+
+impl B for () {
+ // `'a` doesn't match implicit `'static`: suggest `'_`
+ type T<'a> = Box<dyn A + 'a>; //~ incompatible lifetime on type
+}
+
+trait C {}
+impl C for Box<dyn A + 'static> {}
+pub trait D {
+ type T<'a>: C;
+}
+impl D for () {
+ // `'a` doesn't match explicit `'static`: we *should* suggest removing `'static`
+ type T<'a> = Box<dyn A + 'a>; //~ incompatible lifetime on type
+}
+
+trait E {}
+impl E for (Box<dyn A>, Box<dyn A>) {}
+pub trait F {
+ type T<'a>: E;
+}
+impl F for () {
+ // `'a` doesn't match explicit `'static`: suggest `'_`
+ type T<'a> = (Box<dyn A + 'a>, Box<dyn A + 'a>); //~ incompatible lifetime on type
+}
+
+fn main() {}
--- /dev/null
+error: incompatible lifetime on type
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:17:5
+ |
+LL | type T<'a> = Box<dyn A + 'a>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: because this has an unmet lifetime requirement
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:12:17
+ |
+LL | type T<'a>: A;
+ | ^ introduces a `'static` lifetime requirement
+note: the lifetime `'a` as defined on the associated item at 17:12...
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:17:12
+ |
+LL | type T<'a> = Box<dyn A + 'a>;
+ | ^^
+ = note: ...does not necessarily outlive the static lifetime introduced by the compatible `impl`
+note: this has an implicit `'static` lifetime requirement
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:9:20
+ |
+LL | impl A for Box<dyn A> {}
+ | ^
+help: consider relaxing the implicit `'static` requirement
+ |
+LL | impl A for Box<dyn A + '_> {}
+ | ^^^^
+
+error: incompatible lifetime on type
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:27:5
+ |
+LL | type T<'a> = Box<dyn A + 'a>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: because this has an unmet lifetime requirement
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:23:17
+ |
+LL | type T<'a>: C;
+ | ^ introduces a `'static` lifetime requirement
+note: the lifetime `'a` as defined on the associated item at 27:12...
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:27:12
+ |
+LL | type T<'a> = Box<dyn A + 'a>;
+ | ^^
+note: ...does not necessarily outlive the static lifetime introduced by the compatible `impl`
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:21:1
+ |
+LL | impl C for Box<dyn A + 'static> {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: incompatible lifetime on type
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:37:5
+ |
+LL | type T<'a> = (Box<dyn A + 'a>, Box<dyn A + 'a>);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: because this has an unmet lifetime requirement
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:33:17
+ |
+LL | type T<'a>: E;
+ | ^ introduces a `'static` lifetime requirement
+note: the lifetime `'a` as defined on the associated item at 37:12...
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:37:12
+ |
+LL | type T<'a> = (Box<dyn A + 'a>, Box<dyn A + 'a>);
+ | ^^
+ = note: ...does not necessarily outlive the static lifetime introduced by the compatible `impl`
+note: this has an implicit `'static` lifetime requirement
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:31:21
+ |
+LL | impl E for (Box<dyn A>, Box<dyn A>) {}
+ | ^
+note: this has an implicit `'static` lifetime requirement
+ --> $DIR/issue-78113-lifetime-mismatch-dyn-trait-box.rs:31:33
+ |
+LL | impl E for (Box<dyn A>, Box<dyn A>) {}
+ | ^
+help: consider relaxing the implicit `'static` requirement
+ |
+LL | impl E for (Box<dyn A + '_>, Box<dyn A>) {}
+ | ^^^^
+help: consider relaxing the implicit `'static` requirement
+ |
+LL | impl E for (Box<dyn A>, Box<dyn A + '_>) {}
+ | ^^^^
+
+error: aborting due to 3 previous errors
+
--- /dev/null
+// build-pass
+
+#![feature(generic_associated_types)]
+
+trait Trait {
+ type Ref<'a>;
+}
+
+impl Trait for () {
+ type Ref<'a> = &'a i8;
+}
+
+struct RefRef<'a, T: Trait>(&'a <T as Trait>::Ref<'a>);
+
+fn wrap<'a, T: Trait>(reff: &'a <T as Trait>::Ref<'a>) -> RefRef<'a, T> {
+ RefRef(reff)
+}
+
+fn main() {}
error[E0038]: the trait `StreamingIterator` cannot be made into an object
- --> $DIR/trait-objects.rs:10:16
+ --> $DIR/trait-objects.rs:10:21
|
LL | fn min_size(x: &mut dyn for<'a> StreamingIterator<Item<'a> = &'a i32>) -> usize {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `StreamingIterator` cannot be made into an object
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `StreamingIterator` cannot be made into an object
|
= help: consider moving `Item` to another trait
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>
|
LL | impl MyTrait for Foo {
| ^^^- help: indicate the anonymous lifetime: `<'_>`
+ |
+ = note: assuming a `'static` lifetime...
error: aborting due to previous error
|
LL | impl MyTrait for u32 {
| ^^^^^^^- help: indicate the anonymous lifetime: `<'_>`
+ |
+ = note: assuming a `'static` lifetime...
error: aborting due to previous error
+++ /dev/null
-#![allow(incomplete_features)]
-#![feature(impl_trait_in_bindings)]
-
-fn foo() {
- let _ : impl Copy;
- //~^ ERROR cannot resolve opaque type
-}
-
-fn main() {}
+++ /dev/null
-error[E0720]: cannot resolve opaque type
- --> $DIR/binding-without-value.rs:5:13
- |
-LL | let _ : impl Copy;
- | - ^^^^^^^^^ cannot resolve opaque type
- | |
- | this binding might not have a concrete type
- |
-help: set the binding to a value for a concrete type to be resolved
- |
-LL | let _ : impl Copy = /* value */;
- | ^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0720`.
+++ /dev/null
-#![feature(impl_trait_in_bindings)]
-//~^ WARN the feature `impl_trait_in_bindings` is incomplete
-
-const FOO: impl Copy = 42;
-
-static BAR: impl Copy = 42;
-
-fn main() {
- let foo: impl Copy = 42;
-
- let _ = FOO.count_ones();
-//~^ ERROR no method
- let _ = BAR.count_ones();
-//~^ ERROR no method
- let _ = foo.count_ones();
-//~^ ERROR no method
-}
+++ /dev/null
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/bindings-opaque.rs:1:12
- |
-LL | #![feature(impl_trait_in_bindings)]
- | ^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: `#[warn(incomplete_features)]` on by default
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
-error[E0599]: no method named `count_ones` found for opaque type `impl Copy` in the current scope
- --> $DIR/bindings-opaque.rs:11:17
- |
-LL | let _ = FOO.count_ones();
- | ^^^^^^^^^^ method not found in `impl Copy`
-
-error[E0599]: no method named `count_ones` found for opaque type `impl Copy` in the current scope
- --> $DIR/bindings-opaque.rs:13:17
- |
-LL | let _ = BAR.count_ones();
- | ^^^^^^^^^^ method not found in `impl Copy`
-
-error[E0599]: no method named `count_ones` found for opaque type `impl Copy` in the current scope
- --> $DIR/bindings-opaque.rs:15:17
- |
-LL | let _ = foo.count_ones();
- | ^^^^^^^^^^ method not found in `impl Copy`
-
-error: aborting due to 3 previous errors; 1 warning emitted
-
-For more information about this error, try `rustc --explain E0599`.
+++ /dev/null
-#![feature(impl_trait_in_bindings)]
-//~^ WARN the feature `impl_trait_in_bindings` is incomplete
-
-fn a<T: Clone>(x: T) {
- const foo: impl Clone = x;
- //~^ ERROR attempt to use a non-constant value in a constant
-}
-
-fn b<T: Clone>(x: T) {
- let _ = move || {
- const foo: impl Clone = x;
- //~^ ERROR attempt to use a non-constant value in a constant
- };
-}
-
-trait Foo<T: Clone> {
- fn a(x: T) {
- const foo: impl Clone = x;
- //~^ ERROR attempt to use a non-constant value in a constant
- }
-}
-
-impl<T: Clone> Foo<T> for i32 {
- fn a(x: T) {
- const foo: impl Clone = x;
- //~^ ERROR attempt to use a non-constant value in a constant
- }
-}
-
-fn main() { }
+++ /dev/null
-error[E0435]: attempt to use a non-constant value in a constant
- --> $DIR/bindings.rs:5:29
- |
-LL | const foo: impl Clone = x;
- | --------- ^ non-constant value
- | |
- | help: consider using `let` instead of `const`: `let foo`
-
-error[E0435]: attempt to use a non-constant value in a constant
- --> $DIR/bindings.rs:11:33
- |
-LL | const foo: impl Clone = x;
- | --------- ^ non-constant value
- | |
- | help: consider using `let` instead of `const`: `let foo`
-
-error[E0435]: attempt to use a non-constant value in a constant
- --> $DIR/bindings.rs:18:33
- |
-LL | const foo: impl Clone = x;
- | --------- ^ non-constant value
- | |
- | help: consider using `let` instead of `const`: `let foo`
-
-error[E0435]: attempt to use a non-constant value in a constant
- --> $DIR/bindings.rs:25:33
- |
-LL | const foo: impl Clone = x;
- | --------- ^ non-constant value
- | |
- | help: consider using `let` instead of `const`: `let foo`
-
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/bindings.rs:1:12
- |
-LL | #![feature(impl_trait_in_bindings)]
- | ^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: `#[warn(incomplete_features)]` on by default
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
-error: aborting due to 4 previous errors; 1 warning emitted
-
-For more information about this error, try `rustc --explain E0435`.
// edition:2018
-#![feature(impl_trait_in_bindings)]
-//~^ WARNING the feature `impl_trait_in_bindings` is incomplete
-
// See issue 60414
// Reduction to `impl Trait`
struct Foo<T>(T);
-trait FooLike { type Output; }
+trait FooLike {
+ type Output;
+}
impl<T> FooLike for Foo<T> {
type Output = T;
}
/// `T::Assoc` can't be normalized any further here.
- fn foo_fail<T: Trait>() -> impl FooLike<Output=T::Assoc> {
+ fn foo_fail<T: Trait>() -> impl FooLike<Output = T::Assoc> {
//~^ ERROR: type mismatch
Foo(())
}
}
/// Missing bound constraining `Assoc`, `T::Assoc` can't be normalized further.
- fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output=T::Assoc> {
- //~^ ERROR: type mismatch
- //~^^ ERROR `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
+ fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output = T::Assoc> {
+ //~^ ERROR: type mismatch
+ //~^^ ERROR `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
Foo(())
}
}
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/bound-normalization-fail.rs:3:12
- |
-LL | #![feature(impl_trait_in_bindings)]
- | ^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: `#[warn(incomplete_features)]` on by default
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as impl_trait::Trait>::Assoc`
- --> $DIR/bound-normalization-fail.rs:26:32
+ --> $DIR/bound-normalization-fail.rs:25:32
|
-LL | fn foo_fail<T: Trait>() -> impl FooLike<Output=T::Assoc> {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found `()`
+LL | fn foo_fail<T: Trait>() -> impl FooLike<Output = T::Assoc> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found `()`
|
= note: expected associated type `<T as impl_trait::Trait>::Assoc`
found type `()`
help: consider constraining the associated type `<T as impl_trait::Trait>::Assoc` to `()`
|
-LL | fn foo_fail<T: Trait<Assoc = ()>>() -> impl FooLike<Output=T::Assoc> {
+LL | fn foo_fail<T: Trait<Assoc = ()>>() -> impl FooLike<Output = T::Assoc> {
| ^^^^^^^^^^^^
error[E0760]: `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
- --> $DIR/bound-normalization-fail.rs:42:41
+ --> $DIR/bound-normalization-fail.rs:41:41
|
-LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output=T::Assoc> {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output = T::Assoc> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as lifetimes::Trait<'static>>::Assoc`
- --> $DIR/bound-normalization-fail.rs:42:41
+ --> $DIR/bound-normalization-fail.rs:41:41
|
-LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output=T::Assoc> {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found `()`
+LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output = T::Assoc> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found `()`
|
= note: expected associated type `<T as lifetimes::Trait<'static>>::Assoc`
found type `()`
help: consider constraining the associated type `<T as lifetimes::Trait<'static>>::Assoc` to `()`
|
-LL | fn foo2_fail<'a, T: Trait<'a, Assoc = ()>>() -> impl FooLike<Output=T::Assoc> {
+LL | fn foo2_fail<'a, T: Trait<'a, Assoc = ()>>() -> impl FooLike<Output = T::Assoc> {
| ^^^^^^^^^^^^
-error: aborting due to 3 previous errors; 1 warning emitted
+error: aborting due to 3 previous errors
Some errors have detailed explanations: E0271, E0760.
For more information about an error, try `rustc --explain E0271`.
+++ /dev/null
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/bound-normalization-pass.rs:8:12
- |
-LL | #![feature(impl_trait_in_bindings)]
- | ^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: `#[warn(incomplete_features)]` on by default
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
-warning: 1 warning emitted
-
//-^ To make this the regression test for #75962.
#![feature(min_type_alias_impl_trait)]
-#![feature(impl_trait_in_bindings)]
-//~^ WARNING the feature `impl_trait_in_bindings` is incomplete
// See issue 60414
struct Foo<T>(T);
-trait FooLike { type Output; }
+trait FooLike {
+ type Output;
+}
impl<T> FooLike for Foo<T> {
type Output = T;
}
/// `T::Assoc` should be normalized to `()` here.
- fn foo_pass<T: Trait<Assoc=()>>() -> impl FooLike<Output=T::Assoc> {
+ fn foo_pass<T: Trait<Assoc = ()>>() -> impl FooLike<Output = T::Assoc> {
Foo(())
}
}
/// Like above.
///
/// FIXME(#51525) -- the shorter notation `T::Assoc` winds up referencing `'static` here
- fn foo2_pass<'a, T: Trait<'a, Assoc=()> + 'a>(
- ) -> impl FooLike<Output=<T as Trait<'a>>::Assoc> + 'a {
+ fn foo2_pass<'a, T: Trait<'a, Assoc = ()> + 'a>()
+ -> impl FooLike<Output = <T as Trait<'a>>::Assoc> + 'a {
Foo(())
}
/// Normalization to type containing bound region.
///
/// FIXME(#51525) -- the shorter notation `T::Assoc` winds up referencing `'static` here
- fn foo2_pass2<'a, T: Trait<'a, Assoc=&'a ()> + 'a>(
- ) -> impl FooLike<Output=<T as Trait<'a>>::Assoc> + 'a {
+ fn foo2_pass2<'a, T: Trait<'a, Assoc = &'a ()> + 'a>()
+ -> impl FooLike<Output = <T as Trait<'a>>::Assoc> + 'a {
Foo(&())
}
}
-// Reduction using `impl Trait` in bindings
-
-mod impl_trait_in_bindings {
- struct Foo;
-
- trait FooLike { type Output; }
-
- impl FooLike for Foo {
- type Output = u32;
- }
-
- trait Trait {
- type Assoc;
- }
-
- fn foo<T: Trait<Assoc=u32>>() {
- let _: impl FooLike<Output=T::Assoc> = Foo;
- }
-}
-
// The same applied to `type Foo = impl Bar`s
mod opaque_types {
+++ /dev/null
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/bound-normalization-pass.rs:8:12
- |
-LL | #![feature(impl_trait_in_bindings)]
- | ^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: `#[warn(incomplete_features)]` on by default
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
-warning: 1 warning emitted
-
+++ /dev/null
-// check-pass
-
-#![feature(impl_trait_in_bindings)]
-//~^ WARN the feature `impl_trait_in_bindings` is incomplete
-
-const _: impl Fn() = ||();
-
-fn main() {}
+++ /dev/null
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/impl-trait-in-bindings-issue-73003.rs:3:12
- |
-LL | #![feature(impl_trait_in_bindings)]
- | ^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: `#[warn(incomplete_features)]` on by default
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
-warning: 1 warning emitted
-
+++ /dev/null
-// run-pass
-
-#![feature(impl_trait_in_bindings)]
-//~^ WARN the feature `impl_trait_in_bindings` is incomplete
-
-use std::fmt::Debug;
-
-const FOO: impl Debug + Clone + PartialEq<i32> = 42;
-
-static BAR: impl Debug + Clone + PartialEq<i32> = 42;
-
-fn a<T: Clone>(x: T) {
- let y: impl Clone = x;
- let _ = y.clone();
-}
-
-fn b<T: Clone>(x: T) {
- let f = move || {
- let y: impl Clone = x;
- let _ = y.clone();
- };
- f();
-}
-
-trait Foo<T: Clone> {
- fn a(x: T) {
- let y: impl Clone = x;
- let _ = y.clone();
- }
-}
-
-impl<T: Clone> Foo<T> for i32 {
- fn a(x: T) {
- let y: impl Clone = x;
- let _ = y.clone();
- }
-}
-
-fn main() {
- let foo: impl Debug + Clone + PartialEq<i32> = 42;
-
- assert_eq!(FOO.clone(), 42);
- assert_eq!(BAR.clone(), 42);
- assert_eq!(foo.clone(), 42);
-
- a(42);
- b(42);
- i32::a(42);
-}
+++ /dev/null
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/impl-trait-in-bindings.rs:3:12
- |
-LL | #![feature(impl_trait_in_bindings)]
- | ^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: `#[warn(incomplete_features)]` on by default
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
-warning: 1 warning emitted
-
+++ /dev/null
-// Regression test for #57200
-// FIXME: The error is temporary hack, we'll revisit here at some point.
-
-#![feature(impl_trait_in_bindings)]
-#![allow(incomplete_features)]
-
-fn bug<'a, 'b, T>()
-where
- 'a: 'b,
-{
- let f: impl Fn(&'a T) -> &'b T = |x| x;
- //~^ ERROR: lifetimes in impl Trait types in bindings are not currently supported
-}
-
-fn main() {}
+++ /dev/null
-error: lifetimes in impl Trait types in bindings are not currently supported
- --> $DIR/issue-57200.rs:11:12
- |
-LL | let f: impl Fn(&'a T) -> &'b T = |x| x;
- | ^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
+++ /dev/null
-// Regression test for #57201
-// FIXME: The error is temporary hack, we'll revisit here at some point.
-
-#![feature(impl_trait_in_bindings)]
-#![allow(incomplete_features)]
-
-fn bug<'a, 'b, T>()
-where
- 'a: 'b,
-{
- let f: &impl Fn(&'a T) -> &'b T = &|x| x;
- //~^ ERROR: lifetimes in impl Trait types in bindings are not currently supported
-}
-
-fn main() {}
+++ /dev/null
-error: lifetimes in impl Trait types in bindings are not currently supported
- --> $DIR/issue-57201.rs:11:13
- |
-LL | let f: &impl Fn(&'a T) -> &'b T = &|x| x;
- | ^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
+++ /dev/null
-// Regression test for #60473
-
-#![feature(impl_trait_in_bindings)]
-#![allow(incomplete_features)]
-
-struct A<'a>(&'a ());
-
-trait Trait<T> {}
-
-impl<T> Trait<T> for () {}
-
-fn main() {
- let x: impl Trait<A> = ();
- //~^ ERROR: missing lifetime specifier
-}
+++ /dev/null
-error[E0106]: missing lifetime specifier
- --> $DIR/issue-60473.rs:13:23
- |
-LL | let x: impl Trait<A> = ();
- | ^ expected named lifetime parameter
- |
-help: consider introducing a named lifetime parameter
- |
-LL | fn main<'a>() {
-LL | let x: impl Trait<A<'a>> = ();
- |
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0106`.
+++ /dev/null
-// Regression test for #67166
-
-#![feature(impl_trait_in_bindings)]
-#![allow(incomplete_features)]
-
-pub fn run() {
- let _foo: Box<impl Copy + '_> = Box::new(());
- //~^ ERROR: missing lifetime specifier
-}
-
-fn main() {}
+++ /dev/null
-error[E0106]: missing lifetime specifier
- --> $DIR/issue-67166.rs:7:31
- |
-LL | let _foo: Box<impl Copy + '_> = Box::new(());
- | ^^ expected named lifetime parameter
- |
-help: consider introducing a named lifetime parameter
- |
-LL | pub fn run<'a>() {
-LL | let _foo: Box<impl Copy + 'a> = Box::new(());
- |
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0106`.
+++ /dev/null
-// check-pass
-
-#![feature(impl_trait_in_bindings)]
-#![allow(incomplete_features)]
-
-struct A<'a>(&'a ());
-
-trait Trait<T> {}
-
-impl<T> Trait<T> for () {}
-
-pub fn foo<'a>() {
- let _x: impl Trait<A<'a>> = ();
-}
-
-fn main() {}
error[E0271]: type mismatch resolving `<Bar as Iterator>::Item == Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> Option<String> + 'static)>`
- --> $DIR/issue-70877.rs:11:12
+ --> $DIR/issue-70877.rs:10:12
|
LL | type FooRet = impl std::fmt::Debug;
| -------------------- the found opaque type
error[E0271]: type mismatch resolving `<Bar as Iterator>::Item == Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> Option<String> + 'static)>`
- --> $DIR/issue-70877.rs:11:12
+ --> $DIR/issue-70877.rs:10:12
|
LL | type FooRet = impl std::fmt::Debug;
| -------------------- the found opaque type
// revisions: min_tait full_tait
#![feature(min_type_alias_impl_trait)]
#![cfg_attr(full_tait, feature(type_alias_impl_trait))]
-#![feature(impl_trait_in_bindings)]
#![allow(incomplete_features)]
type FooArg<'a> = &'a dyn ToString;
+++ /dev/null
-// edition:2018
-
-#![feature(impl_trait_in_bindings)]
-//~^ WARN the feature `impl_trait_in_bindings` is incomplete
-
-struct Bug {
- V1: [(); {
- let f: impl core::future::Future<Output = u8> = async { 1 };
- //~^ ERROR `async` blocks are not allowed in constants
- //~| ERROR destructors cannot be evaluated at compile-time
- 1
- }],
-}
-
-fn main() {}
+++ /dev/null
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/issue-78721.rs:3:12
- |
-LL | #![feature(impl_trait_in_bindings)]
- | ^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: `#[warn(incomplete_features)]` on by default
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
-error[E0658]: `async` blocks are not allowed in constants
- --> $DIR/issue-78721.rs:8:57
- |
-LL | let f: impl core::future::Future<Output = u8> = async { 1 };
- | ^^^^^^^^^^^
- |
- = note: see issue #85368 <https://github.com/rust-lang/rust/issues/85368> for more information
- = help: add `#![feature(const_async_blocks)]` to the crate attributes to enable
-
-error[E0493]: destructors cannot be evaluated at compile-time
- --> $DIR/issue-78721.rs:8:13
- |
-LL | let f: impl core::future::Future<Output = u8> = async { 1 };
- | ^ constants cannot evaluate destructors
-...
-LL | }],
- | - value is dropped here
-
-error: aborting due to 2 previous errors; 1 warning emitted
-
-Some errors have detailed explanations: E0493, E0658.
-For more information about an error, try `rustc --explain E0493`.
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/issue-78722.rs:7:12
- |
-LL | #![feature(impl_trait_in_bindings)]
- | ^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
-error[E0658]: `async` blocks are not allowed in constants
- --> $DIR/issue-78722.rs:17:20
+error[E0308]: mismatched types
+ --> $DIR/issue-78722.rs:15:20
|
+LL | type F = impl core::future::Future<Output = u8>;
+ | -------------------------------------- the expected opaque type
+...
LL | let f: F = async { 1 };
- | ^^^^^^^^^^^
+ | - ^^^^^^^^^^^ expected opaque type, found a different opaque type
+ | |
+ | expected due to this
+ |
+ ::: $SRC_DIR/core/src/future/mod.rs:LL:COL
|
- = note: see issue #85368 <https://github.com/rust-lang/rust/issues/85368> for more information
- = help: add `#![feature(const_async_blocks)]` to the crate attributes to enable
-
-error[E0493]: destructors cannot be evaluated at compile-time
- --> $DIR/issue-78722.rs:17:13
+LL | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
+ | ------------------------------- the found opaque type
|
-LL | let f: F = async { 1 };
- | ^ constants cannot evaluate destructors
-...
-LL | }],
- | - value is dropped here
+ = note: expected opaque type `impl Future` (opaque type at <$DIR/issue-78722.rs:8:10>)
+ found opaque type `impl Future` (opaque type at <$SRC_DIR/core/src/future/mod.rs:LL:COL>)
+ = note: distinct uses of `impl Trait` result in different opaque types
-error: aborting due to 2 previous errors; 2 warnings emitted
+error: aborting due to previous error; 1 warning emitted
-Some errors have detailed explanations: E0493, E0658.
-For more information about an error, try `rustc --explain E0493`.
+For more information about this error, try `rustc --explain E0308`.
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/issue-78722.rs:7:12
- |
-LL | #![feature(impl_trait_in_bindings)]
- | ^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: `#[warn(incomplete_features)]` on by default
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
-error[E0658]: `async` blocks are not allowed in constants
- --> $DIR/issue-78722.rs:17:20
+error[E0308]: mismatched types
+ --> $DIR/issue-78722.rs:15:20
|
+LL | type F = impl core::future::Future<Output = u8>;
+ | -------------------------------------- the expected opaque type
+...
LL | let f: F = async { 1 };
- | ^^^^^^^^^^^
+ | - ^^^^^^^^^^^ expected opaque type, found a different opaque type
+ | |
+ | expected due to this
+ |
+ ::: $SRC_DIR/core/src/future/mod.rs:LL:COL
|
- = note: see issue #85368 <https://github.com/rust-lang/rust/issues/85368> for more information
- = help: add `#![feature(const_async_blocks)]` to the crate attributes to enable
-
-error[E0493]: destructors cannot be evaluated at compile-time
- --> $DIR/issue-78722.rs:17:13
+LL | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
+ | ------------------------------- the found opaque type
|
-LL | let f: F = async { 1 };
- | ^ constants cannot evaluate destructors
-...
-LL | }],
- | - value is dropped here
+ = note: expected opaque type `impl Future` (opaque type at <$DIR/issue-78722.rs:8:10>)
+ found opaque type `impl Future` (opaque type at <$SRC_DIR/core/src/future/mod.rs:LL:COL>)
+ = note: distinct uses of `impl Trait` result in different opaque types
-error: aborting due to 2 previous errors; 1 warning emitted
+error: aborting due to previous error
-Some errors have detailed explanations: E0493, E0658.
-For more information about an error, try `rustc --explain E0493`.
+For more information about this error, try `rustc --explain E0308`.
#![feature(min_type_alias_impl_trait)]
#![cfg_attr(full_tait, feature(type_alias_impl_trait))]
//[full_tait]~^ WARN incomplete
-#![feature(impl_trait_in_bindings)]
-//~^ WARN the feature `impl_trait_in_bindings` is incomplete
type F = impl core::future::Future<Output = u8>;
async {}
}
let f: F = async { 1 };
- //~^ ERROR `async` blocks are not allowed in constants
- //~| ERROR destructors cannot be evaluated at compile-time
+ //~^ ERROR mismatched types [E0308]
1
}],
}
struct Foo<T = impl Copy>(T);
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
type Result<T, E = impl std::error::Error> = std::result::Result<T, E>;
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
// should not cause ICE
fn x() -> Foo {
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/issue-83929-impl-trait-in-generic-default.rs:1:16
|
LL | struct Foo<T = impl Copy>(T);
| ^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/issue-83929-impl-trait-in-generic-default.rs:4:20
|
LL | type Result<T, E = impl std::error::Error> = std::result::Result<T, E>;
help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a bound
|
LL | fn elided(x: &i32) -> impl Copy + '_ { x }
- | ^^^^^^^^^^^^^^
+ | ^^^^
error: lifetime may not live long enough
--> $DIR/must_outlive_least_region_or_bound.rs:5:32
help: to allow this `impl Trait` to capture borrowed data with lifetime `'a`, add `'a` as a bound
|
LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x }
- | ^^^^^^^^^^^^^^
+ | ^^^^
error: lifetime may not live long enough
--> $DIR/must_outlive_least_region_or_bound.rs:7:46
| | nested `impl Trait` here
| outer `impl Trait`
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/nested_impl_trait.rs:8:32
|
LL | fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {}
| ^^^^^^^^^^^^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/nested_impl_trait.rs:25:42
|
LL | fn allowed_in_ret_type() -> impl Fn() -> impl Into<u32> {
help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a bound
|
LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> + '_ {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^
error: lifetime may not live long enough
--> $DIR/static-return-lifetime-infered.rs:9:37
help: to allow this `impl Trait` to capture borrowed data with lifetime `'a`, add `'a` as a bound
|
LL | fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> + 'a {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^
error: aborting due to 2 previous errors
// Disallowed
fn in_fn_parameter_in_parameters(_: fn(impl Debug)) { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
// Disallowed
fn in_fn_return_in_parameters(_: fn() -> impl Debug) { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
// Disallowed
fn in_fn_parameter_in_return() -> fn(impl Debug) { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
// Disallowed
fn in_fn_return_in_return() -> fn() -> impl Debug { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
// Disallowed
fn in_dyn_Fn_parameter_in_parameters(_: &dyn Fn(impl Debug)) { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
// Disallowed
fn in_dyn_Fn_return_in_parameters(_: &dyn Fn() -> impl Debug) { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
// Disallowed
fn in_dyn_Fn_parameter_in_return() -> &'static dyn Fn(impl Debug) { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
// Disallowed
fn in_dyn_Fn_return_in_return() -> &'static dyn Fn() -> impl Debug { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
// Disallowed
fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
//~^^ ERROR nested `impl Trait` is not allowed
// Disallowed
fn in_impl_Fn_return_in_parameters(_: &impl Fn() -> impl Debug) { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
// Disallowed
fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
//~| ERROR nested `impl Trait` is not allowed
// Disallowed
fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
// Disallowed
fn in_Fn_parameter_in_generics<F: Fn(impl Debug)> (_: F) { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
// Disallowed
fn in_Fn_return_in_generics<F: Fn() -> impl Debug> (_: F) { panic!() }
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
// Allowed
// Disallowed
struct InBraceStructField { x: impl Debug }
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
// Disallowed
struct InAdtInBraceStructField { x: Vec<impl Debug> }
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
// Disallowed
struct InTupleStructField(impl Debug);
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
// Disallowed
enum InEnum {
InBraceVariant { x: impl Debug },
- //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+ //~^ ERROR `impl Trait` not allowed outside of function and method return types
InTupleVariant(impl Debug),
- //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+ //~^ ERROR `impl Trait` not allowed outside of function and method return types
}
// Allowed
// Disallowed
trait InTraitDefnReturn {
fn in_return() -> impl Debug;
- //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+ //~^ ERROR `impl Trait` not allowed outside of function and method return types
}
// Allowed and disallowed in trait impls
// Allowed
fn in_trait_impl_return() -> impl Debug { () }
- //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+ //~^ ERROR `impl Trait` not allowed outside of function and method return types
}
// Allowed
// Disallowed
extern "C" {
fn in_foreign_parameters(_: impl Debug);
- //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+ //~^ ERROR `impl Trait` not allowed outside of function and method return types
fn in_foreign_return() -> impl Debug;
- //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+ //~^ ERROR `impl Trait` not allowed outside of function and method return types
}
// Allowed
//~^ ERROR `impl Trait` in type aliases is unstable
type InReturnInTypeAlias<R> = fn() -> impl Debug;
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
//~| ERROR `impl Trait` in type aliases is unstable
// Disallowed in impl headers
impl PartialEq<impl Debug> for () {
- //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+ //~^ ERROR `impl Trait` not allowed outside of function and method return types
}
// Disallowed in impl headers
impl PartialEq<()> for impl Debug {
- //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+ //~^ ERROR `impl Trait` not allowed outside of function and method return types
}
// Disallowed in inherent impls
impl impl Debug {
- //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+ //~^ ERROR `impl Trait` not allowed outside of function and method return types
}
// Disallowed in inherent impls
struct InInherentImplAdt<T> { t: T }
impl InInherentImplAdt<impl Debug> {
- //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+ //~^ ERROR `impl Trait` not allowed outside of function and method return types
}
// Disallowed in where clauses
fn in_fn_where_clause()
where impl Debug: Debug
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
{
}
// Disallowed in where clauses
fn in_adt_in_fn_where_clause()
where Vec<impl Debug>: Debug
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
{
}
// Disallowed
fn in_trait_parameter_in_fn_where_clause<T>()
where T: PartialEq<impl Debug>
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
{
}
// Disallowed
fn in_Fn_parameter_in_fn_where_clause<T>()
where T: Fn(impl Debug)
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
{
}
// Disallowed
fn in_Fn_return_in_fn_where_clause<T>()
where T: Fn() -> impl Debug
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
{
}
// Disallowed
struct InStructGenericParamDefault<T = impl Debug>(T);
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
// Disallowed
enum InEnumGenericParamDefault<T = impl Debug> { Variant(T) }
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
// Disallowed
trait InTraitGenericParamDefault<T = impl Debug> {}
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
// Disallowed
type InTypeAliasGenericParamDefault<T = impl Debug> = T;
-//~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~^ ERROR `impl Trait` not allowed outside of function and method return types
// Disallowed
impl <T = impl Debug> T {}
//~^ ERROR defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
//~| WARNING this was previously accepted by the compiler but is being phased out
-//~| ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~| ERROR `impl Trait` not allowed outside of function and method return types
// Disallowed
fn in_method_generic_param_default<T = impl Debug>(_: T) {}
//~^ ERROR defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
//~| WARNING this was previously accepted by the compiler but is being phased out
-//~| ERROR `impl Trait` not allowed outside of function and inherent method return types
+//~| ERROR `impl Trait` not allowed outside of function and method return types
fn main() {
let _in_local_variable: impl Fn() = || {};
- //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+ //~^ ERROR `impl Trait` not allowed outside of function and method return types
let _in_return_in_local_variable = || -> impl Fn() { || {} };
- //~^ ERROR `impl Trait` not allowed outside of function and inherent method return types
+ //~^ ERROR `impl Trait` not allowed outside of function and method return types
}
= note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
= help: add `#![feature(min_type_alias_impl_trait)]` to the crate attributes to enable
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:15:40
|
LL | fn in_fn_parameter_in_parameters(_: fn(impl Debug)) { panic!() }
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:19:42
|
LL | fn in_fn_return_in_parameters(_: fn() -> impl Debug) { panic!() }
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:23:38
|
LL | fn in_fn_parameter_in_return() -> fn(impl Debug) { panic!() }
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:27:40
|
LL | fn in_fn_return_in_return() -> fn() -> impl Debug { panic!() }
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:31:49
|
LL | fn in_dyn_Fn_parameter_in_parameters(_: &dyn Fn(impl Debug)) { panic!() }
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:35:51
|
LL | fn in_dyn_Fn_return_in_parameters(_: &dyn Fn() -> impl Debug) { panic!() }
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:39:55
|
LL | fn in_dyn_Fn_parameter_in_return() -> &'static dyn Fn(impl Debug) { panic!() }
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:43:57
|
LL | fn in_dyn_Fn_return_in_return() -> &'static dyn Fn() -> impl Debug { panic!() }
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:47:51
|
LL | fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() }
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:52:53
|
LL | fn in_impl_Fn_return_in_parameters(_: &impl Fn() -> impl Debug) { panic!() }
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:56:57
|
LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() }
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:61:59
|
LL | fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { panic!() }
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:65:38
|
LL | fn in_Fn_parameter_in_generics<F: Fn(impl Debug)> (_: F) { panic!() }
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:69:40
|
LL | fn in_Fn_return_in_generics<F: Fn() -> impl Debug> (_: F) { panic!() }
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:82:32
|
LL | struct InBraceStructField { x: impl Debug }
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:86:41
|
LL | struct InAdtInBraceStructField { x: Vec<impl Debug> }
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:90:27
|
LL | struct InTupleStructField(impl Debug);
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:95:25
|
LL | InBraceVariant { x: impl Debug },
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:97:20
|
LL | InTupleVariant(impl Debug),
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:108:23
|
LL | fn in_return() -> impl Debug;
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:125:34
|
LL | fn in_trait_impl_return() -> impl Debug { () }
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:138:33
|
LL | fn in_foreign_parameters(_: impl Debug);
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:141:31
|
LL | fn in_foreign_return() -> impl Debug;
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:157:39
|
LL | type InReturnInTypeAlias<R> = fn() -> impl Debug;
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:162:16
|
LL | impl PartialEq<impl Debug> for () {
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:167:24
|
LL | impl PartialEq<()> for impl Debug {
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:172:6
|
LL | impl impl Debug {
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:178:24
|
LL | impl InInherentImplAdt<impl Debug> {
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:184:11
|
LL | where impl Debug: Debug
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:191:15
|
LL | where Vec<impl Debug>: Debug
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:198:24
|
LL | where T: PartialEq<impl Debug>
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:205:17
|
LL | where T: Fn(impl Debug)
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:212:22
|
LL | where T: Fn() -> impl Debug
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:218:40
|
LL | struct InStructGenericParamDefault<T = impl Debug>(T);
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:222:36
|
LL | enum InEnumGenericParamDefault<T = impl Debug> { Variant(T) }
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:226:38
|
LL | trait InTraitGenericParamDefault<T = impl Debug> {}
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:230:41
|
LL | type InTypeAliasGenericParamDefault<T = impl Debug> = T;
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:234:11
|
LL | impl <T = impl Debug> T {}
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:240:40
|
LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
| ^^^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:246:29
|
LL | let _in_local_variable: impl Fn() = || {};
| ^^^^^^^^^
- |
- = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/where-allowed.rs:248:46
|
LL | let _in_return_in_local_variable = || -> impl Fn() { || {} };
+++ /dev/null
-// edition:2018
-#![feature(impl_trait_in_bindings)]
-//~^ WARN the feature `impl_trait_in_bindings` is incomplete
-
-use std::io::Error;
-
-fn make_unit() -> Result<(), Error> {
- Ok(())
-}
-
-fn main() {
- let fut = async {
- make_unit()?;
-
- Ok(()) //~ ERROR type annotations needed
- };
-}
+++ /dev/null
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/cannot-infer-async-enabled-impl-trait-bindings.rs:2:12
- |
-LL | #![feature(impl_trait_in_bindings)]
- | ^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: `#[warn(incomplete_features)]` on by default
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
-error[E0282]: type annotations needed for `impl Future`
- --> $DIR/cannot-infer-async-enabled-impl-trait-bindings.rs:15:9
- |
-LL | let fut = async {
- | --- consider giving `fut` the explicit type `impl Future`, where the type parameter `E` is specified
-...
-LL | Ok(())
- | ^^ cannot infer type for type parameter `E` declared on the enum `Result`
-
-error: aborting due to previous error; 1 warning emitted
-
-For more information about this error, try `rustc --explain E0282`.
|
LL | impl<'self> Serializable<str> for &'self str {
| ^^^^^^^^^^^^^^^^^ help: indicate the anonymous lifetime: `Serializable<'_, str>`
+ |
+ = note: assuming a `'static` lifetime...
error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/issue-10412.rs:6:13
error[E0308]: mismatched types
--> $DIR/issue-12997-2.rs:8:1
|
+LL | #[bench]
+ | -------- in this procedural macro expansion
LL | fn bar(x: isize) { }
| ^^^^^^^^^^^^^^^^^^^^ expected `isize`, found `&mut Bencher`
|
| ^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `[{integer}]`
- = note: required by `Box::<T>::new`
+note: required by `Box::<T>::new`
+ --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
+ |
+LL | pub fn new(x: T) -> Self {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the size for values of type `[{integer}]` cannot be known at compilation time
--> $DIR/issue-17651.rs:5:9
error[E0277]: the trait bound `isize: HasState` is not satisfied
- --> $DIR/issue-18611.rs:1:4
+ --> $DIR/issue-18611.rs:1:18
|
LL | fn add_state(op: <isize as HasState>::State) {
- | ^^^^^^^^^ the trait `HasState` is not implemented for `isize`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HasState` is not implemented for `isize`
+...
+LL | trait HasState {
+ | -------------- required by this bound in `HasState`
error: aborting due to previous error
error[E0038]: the trait `Bar` cannot be made into an object
- --> $DIR/issue-18959.rs:11:11
+ --> $DIR/issue-18959.rs:11:12
|
LL | fn foo(b: &dyn Bar) {
- | ^^^^^^^^ `Bar` cannot be made into an object
+ | ^^^^^^^ `Bar` cannot be made into an object
|
= help: consider moving `foo` to another trait
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>
|
= help: the trait `Sized` is not implemented for `dyn Iterator<Item = &'a mut u8>`
= note: required because of the requirements on the impl of `IntoIterator` for `dyn Iterator<Item = &'a mut u8>`
- = note: required by `into_iter`
+note: required by `into_iter`
+ --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+ |
+LL | fn into_iter(self) -> Self::IntoIter;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
error[E0277]: the trait bound `Bar: Hash` is not satisfied
--> $DIR/issue-21160.rs:8:12
|
+LL | #[derive(Hash)]
+ | ---- in this derive macro expansion
LL | struct Foo(Bar);
| ^^^ the trait `Hash` is not implemented for `Bar`
|
|
LL | Foo::foo(&f);
| ^^^ private associated function
+ |
+ ::: $DIR/auxiliary/issue-21202.rs:4:9
+ |
+LL | fn foo(&self) { }
+ | ------------- private associated function defined here
error: aborting due to previous error
| ^^^^^^^ `()` is not an iterator
|
= help: the trait `Iterator` is not implemented for `()`
- = note: required by `std::iter::Iterator::next`
+note: required by `std::iter::Iterator::next`
+ --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+ |
+LL | fn next(&mut self) -> Option<Self::Item>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: `bool` is not an iterator
--> $DIR/issue-28098.rs:6:14
|
= help: the trait `Iterator` is not implemented for `bool`
= note: required because of the requirements on the impl of `IntoIterator` for `bool`
- = note: required by `into_iter`
+note: required by `into_iter`
+ --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+ |
+LL | fn into_iter(self) -> Self::IntoIter;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: `()` is not an iterator
--> $DIR/issue-28098.rs:9:28
| ^^^^^^^ `()` is not an iterator
|
= help: the trait `Iterator` is not implemented for `()`
- = note: required by `std::iter::Iterator::next`
+note: required by `std::iter::Iterator::next`
+ --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+ |
+LL | fn next(&mut self) -> Option<Self::Item>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: `()` is not an iterator
--> $DIR/issue-28098.rs:2:13
| ^^^^^^^ `()` is not an iterator
|
= help: the trait `Iterator` is not implemented for `()`
- = note: required by `std::iter::Iterator::next`
+note: required by `std::iter::Iterator::next`
+ --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+ |
+LL | fn next(&mut self) -> Option<Self::Item>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: `()` is not an iterator
--> $DIR/issue-28098.rs:22:28
| ^^^^^^^ `()` is not an iterator
|
= help: the trait `Iterator` is not implemented for `()`
- = note: required by `std::iter::Iterator::next`
+note: required by `std::iter::Iterator::next`
+ --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+ |
+LL | fn next(&mut self) -> Option<Self::Item>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: `bool` is not an iterator
--> $DIR/issue-28098.rs:25:14
|
= help: the trait `Iterator` is not implemented for `bool`
= note: required because of the requirements on the impl of `IntoIterator` for `bool`
- = note: required by `into_iter`
+note: required by `into_iter`
+ --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+ |
+LL | fn into_iter(self) -> Self::IntoIter;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: `()` is not an iterator
--> $DIR/issue-28098.rs:18:13
error[E0283]: type annotations needed
--> $DIR/issue-29147.rs:21:13
|
-LL | trait Foo { fn xxx(&self); }
- | -------------- required by `Foo::xxx`
-...
LL | let _ = <S5<_>>::xxx;
| ^^^^^^^^^^^^ cannot infer type for struct `S5<_>`
|
= note: cannot satisfy `S5<_>: Foo`
+note: required by `Foo::xxx`
+ --> $DIR/issue-29147.rs:10:13
+ |
+LL | trait Foo { fn xxx(&self); }
+ | ^^^^^^^^^^^^^^
error: aborting due to previous error
|
= note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
= note: required because of the requirements on the impl of `FromResidual<Result<Infallible, {integer}>>` for `Result<i32, ()>`
- = note: required by `from_residual`
+note: required by `from_residual`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn from_residual(residual: R) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
found tuple `(&_, &_)`
= note: required because of the requirements on the impl of `Iterator` for `Cloned<std::collections::hash_map::Iter<'_, _, _>>`
= note: required because of the requirements on the impl of `IntoIterator` for `Cloned<std::collections::hash_map::Iter<'_, _, _>>`
- = note: required by `into_iter`
+note: required by `into_iter`
+ --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+ |
+LL | fn into_iter(self) -> Self::IntoIter;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0271]: type mismatch resolving `<std::collections::hash_map::Iter<'_, _, _> as Iterator>::Item == &_`
--> $DIR/issue-33941.rs:4:14
= note: expected reference `&_`
found tuple `(&_, &_)`
= note: required because of the requirements on the impl of `Iterator` for `Cloned<std::collections::hash_map::Iter<'_, _, _>>`
- = note: required by `std::iter::Iterator::next`
+note: required by `std::iter::Iterator::next`
+ --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+ |
+LL | fn next(&mut self) -> Option<Self::Item>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 3 previous errors
--> $DIR/issue-34229.rs:2:46
|
LL | #[derive(PartialEq, PartialOrd)] struct Nope(Comparable);
- | ^^^^^^^^^^ no implementation for `Comparable < Comparable` and `Comparable > Comparable`
+ | ---------- ^^^^^^^^^^ no implementation for `Comparable < Comparable` and `Comparable > Comparable`
+ | |
+ | in this derive macro expansion
|
= help: the trait `PartialOrd` is not implemented for `Comparable`
- = note: required by `std::cmp::PartialOrd::partial_cmp`
+note: required by `std::cmp::PartialOrd::partial_cmp`
+ --> $SRC_DIR/core/src/cmp.rs:LL:COL
+ |
+LL | fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
error[E0624]: associated function `happyfun` is private
--> $DIR/issue-3763.rs:24:18
|
+LL | fn happyfun(&self) {}
+ | ------------------ private associated function defined here
+...
LL | (&my_struct).happyfun();
| ^^^^^^^^ private associated function
error[E0624]: associated function `happyfun` is private
--> $DIR/issue-3763.rs:26:27
|
+LL | fn happyfun(&self) {}
+ | ------------------ private associated function defined here
+...
LL | (Box::new(my_struct)).happyfun();
| ^^^^^^^^ private associated function
error[E0271]: type mismatch resolving `for<'a> <() as Array<'a>>::Element == ()`
--> $DIR/issue-39970.rs:19:5
|
-LL | fn visit() {}
- | ---------- required by `Visit::visit`
-...
LL | <() as Visit>::visit();
| ^^^^^^^^^^^^^^^^^^^^ expected `()`, found `&()`
|
|
LL | impl Visit for () where
| ^^^^^ ^^
+note: required by `Visit::visit`
+ --> $DIR/issue-39970.rs:6:5
+ |
+LL | fn visit() {}
+ | ^^^^^^^^^^
error: aborting due to previous error
struct S;
impl S {
- #[derive(Debug)] //~ ERROR `derive` may only be applied to structs, enums and unions
+ #[derive(Debug)] //~ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s
fn f() {
file!();
}
}
trait Tr1 {
- #[derive(Debug)] //~ ERROR `derive` may only be applied to structs, enums and unions
+ #[derive(Debug)] //~ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s
fn f();
}
trait Tr2 {
- #[derive(Debug)] //~ ERROR `derive` may only be applied to structs, enums and unions
+ #[derive(Debug)] //~ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s
type F;
}
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
--> $DIR/issue-43023.rs:4:5
|
-LL | #[derive(Debug)]
- | ^^^^^^^^^^^^^^^^
+LL | #[derive(Debug)]
+ | ^^^^^^^^^^^^^^^^ not applicable here
+LL | / fn f() {
+LL | | file!();
+LL | | }
+ | |_____- not a `struct`, `enum` or `union`
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
--> $DIR/issue-43023.rs:11:5
|
LL | #[derive(Debug)]
- | ^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^ not applicable here
+LL | fn f();
+ | ------- not a `struct`, `enum` or `union`
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
--> $DIR/issue-43023.rs:16:5
|
LL | #[derive(Debug)]
- | ^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^ not applicable here
+LL | type F;
+ | ------- not a `struct`, `enum` or `union`
error: aborting due to 3 previous errors
LL | break_me::<Type, fn(_)>;
| ^^^^^^^^^^^^^^^^^^^^^^^
| |
- | expected signature of `fn(<Type as Trait<'b>>::Assoc) -> _`
+ | expected signature of `for<'b> fn(<Type as Trait<'b>>::Assoc) -> _`
| found signature of `fn(()) -> _`
error: aborting due to previous error
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/issue-47715.rs:9:37
|
LL | struct Container<T: Iterable<Item = impl Foo>> {
| ^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/issue-47715.rs:14:30
|
LL | enum Enum<T: Iterable<Item = impl Foo>> {
| ^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/issue-47715.rs:19:32
|
LL | union Union<T: Iterable<Item = impl Foo> + Copy> {
| ^^^^^^^^
-error[E0562]: `impl Trait` not allowed outside of function and inherent method return types
+error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/issue-47715.rs:24:30
|
LL | type Type<T: Iterable<Item = impl Foo>> = T;
struct Foo;
// fold_stmt (Mac)
- #[derive(Debug)] //~ ERROR `derive` may only be applied to structs, enums and unions
+ #[derive(Debug)] //~ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s
println!("Hello, world!");
// fold_stmt (Semi)
- #[derive(Debug)] //~ ERROR `derive` may only be applied to structs, enums and unions
+ #[derive(Debug)] //~ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s
"Hello, world!";
// fold_stmt (Local)
- #[derive(Debug)] //~ ERROR `derive` may only be applied to structs, enums and unions
+ #[derive(Debug)] //~ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s
let _ = "Hello, world!";
// visit_expr
let _ = #[derive(Debug)] "Hello, world!";
- //~^ ERROR `derive` may only be applied to structs, enums and unions
+ //~^ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s
let _ = [
// filter_map_expr
- #[derive(Debug)] //~ ERROR `derive` may only be applied to structs, enums and unions
+ #[derive(Debug)] //~ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s
"Hello, world!",
];
}
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
--> $DIR/issue-49934.rs:10:5
|
LL | #[derive(Debug)]
- | ^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^ not applicable here
+LL | println!("Hello, world!");
+ | -------------------------- not a `struct`, `enum` or `union`
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
--> $DIR/issue-49934.rs:14:5
|
LL | #[derive(Debug)]
- | ^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^ not applicable here
+LL | "Hello, world!";
+ | ---------------- not a `struct`, `enum` or `union`
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
--> $DIR/issue-49934.rs:18:5
|
LL | #[derive(Debug)]
- | ^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^ not applicable here
+LL | let _ = "Hello, world!";
+ | ------------------------ not a `struct`, `enum` or `union`
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
--> $DIR/issue-49934.rs:22:13
|
LL | let _ = #[derive(Debug)] "Hello, world!";
- | ^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^ --------------- not a `struct`, `enum` or `union`
+ | |
+ | not applicable here
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
--> $DIR/issue-49934.rs:27:9
|
LL | #[derive(Debug)]
- | ^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^ not applicable here
+LL | "Hello, world!",
+ | --------------- not a `struct`, `enum` or `union`
error: aborting due to 5 previous errors
error[E0624]: associated function `foo` is private
--> $DIR/issue-53498.rs:16:27
|
+LL | fn foo() {}
+ | -------- private associated function defined here
+...
LL | test::Foo::<test::B>::foo();
| ^^^ private associated function
error[E0283]: type annotations needed
--> $DIR/issue-58022.rs:4:25
|
-LL | const SIZE: usize;
- | ------------------ required by `Foo::SIZE`
-LL |
LL | fn new(slice: &[u8; Foo::SIZE]) -> Self;
| ^^^^^^^^^
| |
|
= note: cannot satisfy `_: Foo`
= note: associated constants cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl`
+note: required by `Foo::SIZE`
+ --> $DIR/issue-58022.rs:2:5
+ |
+LL | const SIZE: usize;
+ | ^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
LL | foo((), drop)
| ^^^^
| |
- | expected signature of `fn(<() as Trait<'a>>::Item) -> _`
+ | expected signature of `for<'a> fn(<() as Trait<'a>>::Item) -> _`
| found signature of `fn(()) -> _`
error[E0277]: the size for values of type `<() as Trait<'_>>::Item` cannot be known at compilation time
error[E0277]: the trait bound `(): _Func<_>` is not satisfied
--> $DIR/issue-66353.rs:12:41
|
-LL | fn func(_: Self);
- | ----------------- required by `_Func::func`
-...
LL | _Func::< <() as _A>::AssocT >::func(());
| ^^ the trait `_Func<_>` is not implemented for `()`
+ |
+note: required by `_Func::func`
+ --> $DIR/issue-66353.rs:4:5
+ |
+LL | fn func(_: Self);
+ | ^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
|
= note: cannot satisfy `String: From<&_>`
- = note: required by `from`
+note: required by `from`
+ --> $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ |
+LL | fn from(_: T) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^
error[E0282]: type annotations needed
--> $DIR/issue-72690.rs:11:6
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
|
= note: cannot satisfy `String: From<&_>`
- = note: required by `from`
+note: required by `from`
+ --> $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ |
+LL | fn from(_: T) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^
error[E0283]: type annotations needed
--> $DIR/issue-72690.rs:25:5
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
|
= note: cannot satisfy `String: From<&_>`
- = note: required by `from`
+note: required by `from`
+ --> $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ |
+LL | fn from(_: T) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^
error[E0283]: type annotations needed
--> $DIR/issue-72690.rs:33:5
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
|
= note: cannot satisfy `String: From<&_>`
- = note: required by `from`
+note: required by `from`
+ --> $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ |
+LL | fn from(_: T) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^
error[E0283]: type annotations needed
--> $DIR/issue-72690.rs:41:5
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
|
= note: cannot satisfy `String: From<&_>`
- = note: required by `from`
+note: required by `from`
+ --> $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ |
+LL | fn from(_: T) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^
error[E0283]: type annotations needed
--> $DIR/issue-72690.rs:47:5
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
|
= note: cannot satisfy `String: From<&_>`
- = note: required by `from`
+note: required by `from`
+ --> $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ |
+LL | fn from(_: T) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^
error[E0283]: type annotations needed
--> $DIR/issue-72690.rs:55:5
| ^^^^^^^^^^^^ cannot infer type for reference `&_`
|
= note: cannot satisfy `String: From<&_>`
- = note: required by `from`
+note: required by `from`
+ --> $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ |
+LL | fn from(_: T) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 9 previous errors
--- /dev/null
+// Regression test for issue #87199, where attempting to relax a bound
+// other than the only supported `?Sized` would still cause the compiler
+// to assume that the `Sized` bound was relaxed.
+
+// check-fail
+
+// Check that these function definitions only emit warnings, not errors
+fn arg<T: ?Send>(_: T) {}
+//~^ warning: default bound relaxed for a type parameter, but this does nothing
+fn ref_arg<T: ?Send>(_: &T) {}
+//~^ warning: default bound relaxed for a type parameter, but this does nothing
+fn ret() -> impl Iterator<Item = ()> + ?Send { std::iter::empty() }
+//~^ warning: default bound relaxed for a type parameter, but this does nothing
+
+// Check that there's no `?Sized` relaxation!
+fn main() {
+ ref_arg::<i32>(&5);
+ ref_arg::<[i32]>(&[5]);
+ //~^ the size for values of type `[i32]` cannot be known
+}
--- /dev/null
+warning: default bound relaxed for a type parameter, but this does nothing because the given bound is not a default; only `?Sized` is supported
+ --> $DIR/issue-87199.rs:8:8
+ |
+LL | fn arg<T: ?Send>(_: T) {}
+ | ^
+
+warning: default bound relaxed for a type parameter, but this does nothing because the given bound is not a default; only `?Sized` is supported
+ --> $DIR/issue-87199.rs:10:12
+ |
+LL | fn ref_arg<T: ?Send>(_: &T) {}
+ | ^
+
+warning: default bound relaxed for a type parameter, but this does nothing because the given bound is not a default; only `?Sized` is supported
+ --> $DIR/issue-87199.rs:12:13
+ |
+LL | fn ret() -> impl Iterator<Item = ()> + ?Send { std::iter::empty() }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
+ --> $DIR/issue-87199.rs:18:22
+ |
+LL | fn ref_arg<T: ?Send>(_: &T) {}
+ | - required by this bound in `ref_arg`
+...
+LL | ref_arg::<[i32]>(&[5]);
+ | ^^^^ doesn't have a size known at compile-time
+ |
+ = help: the trait `Sized` is not implemented for `[i32]`
+help: consider relaxing the implicit `Sized` restriction
+ |
+LL | fn ref_arg<T: ?Send + ?Sized>(_: &T) {}
+ | ^^^^^^^^
+
+error: aborting due to previous error; 3 warnings emitted
+
+For more information about this error, try `rustc --explain E0277`.
= help: the trait `Iterator` is not implemented for `{integer}`
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
= note: required because of the requirements on the impl of `IntoIterator` for `{integer}`
- = note: required by `into_iter`
+note: required by `into_iter`
+ --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+ |
+LL | fn into_iter(self) -> Self::IntoIter;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: `u8` is not an iterator
--> $DIR/integral.rs:4:14
= help: the trait `Iterator` is not implemented for `u8`
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
= note: required because of the requirements on the impl of `IntoIterator` for `u8`
- = note: required by `into_iter`
+note: required by `into_iter`
+ --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+ |
+LL | fn into_iter(self) -> Self::IntoIter;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: `i8` is not an iterator
--> $DIR/integral.rs:6:14
= help: the trait `Iterator` is not implemented for `i8`
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
= note: required because of the requirements on the impl of `IntoIterator` for `i8`
- = note: required by `into_iter`
+note: required by `into_iter`
+ --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+ |
+LL | fn into_iter(self) -> Self::IntoIter;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: `u16` is not an iterator
--> $DIR/integral.rs:8:14
= help: the trait `Iterator` is not implemented for `u16`
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
= note: required because of the requirements on the impl of `IntoIterator` for `u16`
- = note: required by `into_iter`
+note: required by `into_iter`
+ --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+ |
+LL | fn into_iter(self) -> Self::IntoIter;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: `i16` is not an iterator
--> $DIR/integral.rs:10:14
= help: the trait `Iterator` is not implemented for `i16`
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
= note: required because of the requirements on the impl of `IntoIterator` for `i16`
- = note: required by `into_iter`
+note: required by `into_iter`
+ --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+ |
+LL | fn into_iter(self) -> Self::IntoIter;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: `u32` is not an iterator
--> $DIR/integral.rs:12:14
= help: the trait `Iterator` is not implemented for `u32`
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
= note: required because of the requirements on the impl of `IntoIterator` for `u32`
- = note: required by `into_iter`
+note: required by `into_iter`
+ --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+ |
+LL | fn into_iter(self) -> Self::IntoIter;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: `i32` is not an iterator
--> $DIR/integral.rs:14:14
= help: the trait `Iterator` is not implemented for `i32`
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
= note: required because of the requirements on the impl of `IntoIterator` for `i32`
- = note: required by `into_iter`
+note: required by `into_iter`
+ --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+ |
+LL | fn into_iter(self) -> Self::IntoIter;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: `u64` is not an iterator
--> $DIR/integral.rs:16:14
= help: the trait `Iterator` is not implemented for `u64`
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
= note: required because of the requirements on the impl of `IntoIterator` for `u64`
- = note: required by `into_iter`
+note: required by `into_iter`
+ --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+ |
+LL | fn into_iter(self) -> Self::IntoIter;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: `i64` is not an iterator
--> $DIR/integral.rs:18:14
= help: the trait `Iterator` is not implemented for `i64`
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
= note: required because of the requirements on the impl of `IntoIterator` for `i64`
- = note: required by `into_iter`
+note: required by `into_iter`
+ --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+ |
+LL | fn into_iter(self) -> Self::IntoIter;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: `usize` is not an iterator
--> $DIR/integral.rs:20:14
= help: the trait `Iterator` is not implemented for `usize`
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
= note: required because of the requirements on the impl of `IntoIterator` for `usize`
- = note: required by `into_iter`
+note: required by `into_iter`
+ --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+ |
+LL | fn into_iter(self) -> Self::IntoIter;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: `isize` is not an iterator
--> $DIR/integral.rs:22:14
= help: the trait `Iterator` is not implemented for `isize`
= note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
= note: required because of the requirements on the impl of `IntoIterator` for `isize`
- = note: required by `into_iter`
+note: required by `into_iter`
+ --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+ |
+LL | fn into_iter(self) -> Self::IntoIter;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: `{float}` is not an iterator
--> $DIR/integral.rs:24:14
|
= help: the trait `Iterator` is not implemented for `{float}`
= note: required because of the requirements on the impl of `IntoIterator` for `{float}`
- = note: required by `into_iter`
+note: required by `into_iter`
+ --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+ |
+LL | fn into_iter(self) -> Self::IntoIter;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 12 previous errors
= help: the trait `Iterator` is not implemented for `RangeTo<{integer}>`
= note: `..end` is a `RangeTo`, which cannot be iterated on; you might have meant to have a bounded `Range`: `0..end`
= note: required because of the requirements on the impl of `IntoIterator` for `RangeTo<{integer}>`
- = note: required by `into_iter`
+note: required by `into_iter`
+ --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+ |
+LL | fn into_iter(self) -> Self::IntoIter;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: `RangeToInclusive<{integer}>` is not an iterator
--> $DIR/ranges.rs:4:14
= help: the trait `Iterator` is not implemented for `RangeToInclusive<{integer}>`
= note: `..=end` is a `RangeToInclusive`, which cannot be iterated on; you might have meant to have a bounded `RangeInclusive`: `0..=end`
= note: required because of the requirements on the impl of `IntoIterator` for `RangeToInclusive<{integer}>`
- = note: required by `into_iter`
+note: required by `into_iter`
+ --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+ |
+LL | fn into_iter(self) -> Self::IntoIter;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
|
= help: the trait `Iterator` is not implemented for `String`
= note: required because of the requirements on the impl of `IntoIterator` for `String`
- = note: required by `into_iter`
+note: required by `into_iter`
+ --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+ |
+LL | fn into_iter(self) -> Self::IntoIter;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: `&str` is not an iterator
--> $DIR/string.rs:4:14
|
= help: the trait `Iterator` is not implemented for `&str`
= note: required because of the requirements on the impl of `IntoIterator` for `&str`
- = note: required by `into_iter`
+note: required by `into_iter`
+ --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+ |
+LL | fn into_iter(self) -> Self::IntoIter;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
--- /dev/null
+error: extern declarations without an explicit ABI are deprecated
+ --> $DIR/cli-lint-override.rs:12:1
+ |
+LL | extern fn foo() {}
+ | ^^^^^^^^^^^^^^^ ABI should be specified here
+ |
+ = note: requested on the command line with `-F missing-abi`
+ = help: the default ABI is C
+
+error: aborting due to previous error
+
--- /dev/null
+warning: extern declarations without an explicit ABI are deprecated
+ --> $DIR/cli-lint-override.rs:12:1
+ |
+LL | extern fn foo() {}
+ | ^^^^^^^^^^^^^^^ ABI should be specified here
+ |
+ = note: requested on the command line with `--force-warn missing-abi`
+ = help: the default ABI is C
+
+warning: 1 warning emitted
+
--- /dev/null
+// Tests that subsequent lints specified via the command line override
+// each other, except for ForceWarn and Forbid, which cannot be overriden.
+//
+// revisions: warn_deny forbid_warn force_warn_deny
+//
+//[warn_deny] compile-flags: --warn missing_abi --deny missing_abi
+//[forbid_warn] compile-flags: --warn missing_abi --forbid missing_abi
+//[force_warn_deny] compile-flags: -Z unstable-options --force-warn missing_abi --allow missing_abi
+//[force_warn_deny] check-pass
+
+
+extern fn foo() {}
+//[warn_deny]~^ ERROR extern declarations without an explicit ABI are deprecated
+//[forbid_warn]~^^ ERROR extern declarations without an explicit ABI are deprecated
+//[force_warn_deny]~^^^ WARN extern declarations without an explicit ABI are deprecated
+
+fn main() {}
--- /dev/null
+error: extern declarations without an explicit ABI are deprecated
+ --> $DIR/cli-lint-override.rs:12:1
+ |
+LL | extern fn foo() {}
+ | ^^^^^^^^^^^^^^^ ABI should be specified here
+ |
+ = note: requested on the command line with `-D missing-abi`
+ = help: the default ABI is C
+
+error: aborting due to previous error
+
--- /dev/null
+// Checks that rustc correctly errors when passed an invalid lint with
+// `--force-warn`. This is a regression test for issue #86958.
+//
+// compile-flags: -Z unstable-options --force-warn foo-qux
+// error-pattern: unknown lint: `foo_qux`
+
+fn main() {}
--- /dev/null
+error[E0602]: unknown lint: `foo_qux`
+ |
+ = note: requested on the command line with `--force-warn foo_qux`
+
+error[E0602]: unknown lint: `foo_qux`
+ |
+ = note: requested on the command line with `--force-warn foo_qux`
+
+error[E0602]: unknown lint: `foo_qux`
+ |
+ = note: requested on the command line with `--force-warn foo_qux`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0602`.
-// compile-flags: --force-warns elided_lifetimes_in_paths -Zunstable-options
+// compile-flags: --force-warn elided_lifetimes_in_paths -Zunstable-options
// check-pass
struct Foo<'a> {
LL | fn foo(x: &Foo) {}
| ^^^- help: indicate the anonymous lifetime: `<'_>`
|
- = note: requested on the command line with `--force-warns elided-lifetimes-in-paths`
+ = note: requested on the command line with `--force-warn elided-lifetimes-in-paths`
warning: 1 warning emitted
-// compile-flags: --force-warns const_err -Zunstable-options
+// compile-flags: --force-warn const_err -Zunstable-options
// check-pass
#![allow(const_err)]
| |
| attempt to divide `1_i32` by zero
|
- = note: requested on the command line with `--force-warns const-err`
+ = note: requested on the command line with `--force-warn const-err`
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
-// compile-flags: --force-warns dead_code -Zunstable-options
+// compile-flags: --force-warn dead_code -Zunstable-options
// check-pass
#![allow(dead_code)]
LL | fn dead_function() {}
| ^^^^^^^^^^^^^
|
- = note: requested on the command line with `--force-warns dead-code`
+ = note: requested on the command line with `--force-warn dead-code`
warning: 1 warning emitted
-// compile-flags: --force-warns const_err -Zunstable-options
+// compile-flags: --force-warn const_err -Zunstable-options
// check-pass
const C: i32 = 1 / 0;
| |
| attempt to divide `1_i32` by zero
|
- = note: requested on the command line with `--force-warns const-err`
+ = note: requested on the command line with `--force-warn const-err`
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
-// compile-flags: --force-warns dead_code -Zunstable-options
+// compile-flags: --force-warn dead_code -Zunstable-options
// check-pass
#![allow(warnings)]
LL | fn dead_function() {}
| ^^^^^^^^^^^^^
|
- = note: requested on the command line with `--force-warns dead-code`
+ = note: requested on the command line with `--force-warn dead-code`
warning: 1 warning emitted
-// compile-flags: --force-warns nonstandard_style -Zunstable-options
+// compile-flags: --force-warn nonstandard_style -Zunstable-options
// check-pass
#![allow(warnings)]
LL | pub fn FUNCTION() {}
| ^^^^^^^^ help: convert the identifier to snake case: `function`
|
- = note: `--force-warns non-snake-case` implied by `--force-warns nonstandard-style`
+ = note: `--force-warn non-snake-case` implied by `--force-warn nonstandard-style`
warning: 1 warning emitted
-// compile-flags: --force-warns bare_trait_objects -Zunstable-options
+// compile-flags: --force-warn bare_trait_objects -Zunstable-options
// check-pass
#![allow(rust_2018_idioms)]
LL | pub fn function(_x: Box<SomeTrait>) {}
| ^^^^^^^^^ help: use `dyn`: `dyn SomeTrait`
|
- = note: requested on the command line with `--force-warns bare-trait-objects`
+ = note: requested on the command line with `--force-warn bare-trait-objects`
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
--- /dev/null
+// compile-flags: --cap-lints allow --force-warn bare_trait_objects -Zunstable-options
+// check-pass
+
+pub trait SomeTrait {}
+
+pub fn function(_x: Box<SomeTrait>) {}
+//~^ WARN trait objects without an explicit `dyn` are deprecated
+//~| WARN this is accepted in the current edition
+
+fn main() {}
--- /dev/null
+warning: trait objects without an explicit `dyn` are deprecated
+ --> $DIR/force-warn-cap-lints-allow.rs:6:25
+ |
+LL | pub fn function(_x: Box<SomeTrait>) {}
+ | ^^^^^^^^^ help: use `dyn`: `dyn SomeTrait`
+ |
+ = note: requested on the command line with `--force-warn bare-trait-objects`
+ = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+ = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
+
+warning: 1 warning emitted
+
-// compile-flags: --cap-lints warn --force-warns rust-2021-compatibility -Zunstable-options
+// compile-flags: --cap-lints warn --force-warn rust-2021-compatibility -Zunstable-options
// check-pass
#![allow(ellipsis_inclusive_range_patterns)]
LL | 0...100 => true,
| ^^^ help: use `..=` for an inclusive range
|
- = note: `--force-warns ellipsis-inclusive-range-patterns` implied by `--force-warns rust-2021-compatibility`
+ = note: `--force-warn ellipsis-inclusive-range-patterns` implied by `--force-warn rust-2021-compatibility`
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
-// compile-flags: --force-warns rust-2018-idioms -Zunstable-options
+// compile-flags: --force-warn rust-2018-idioms -Zunstable-options
// check-pass
#![allow(bare_trait_objects)]
LL | pub fn function(_x: Box<SomeTrait>) {}
| ^^^^^^^^^ help: use `dyn`: `dyn SomeTrait`
|
- = note: `--force-warns bare-trait-objects` implied by `--force-warns rust-2018-idioms`
+ = note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms`
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
-// compile-flags: --force-warns rust_2018_idioms -Zunstable-options
+// compile-flags: --force-warn rust_2018_idioms -Zunstable-options
// check-pass
#![allow(rust_2018_idioms)]
LL | pub fn function(_x: Box<SomeTrait>) {}
| ^^^^^^^^^ help: use `dyn`: `dyn SomeTrait`
|
- = note: `--force-warns bare-trait-objects` implied by `--force-warns rust-2018-idioms`
+ = note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms`
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
+++ /dev/null
-// compile-flags: --cap-lints allow --force-warns bare_trait_objects -Zunstable-options
-// check-pass
-
-pub trait SomeTrait {}
-
-pub fn function(_x: Box<SomeTrait>) {}
-//~^ WARN trait objects without an explicit `dyn` are deprecated
-//~| WARN this is accepted in the current edition
-
-fn main() {}
+++ /dev/null
-warning: trait objects without an explicit `dyn` are deprecated
- --> $DIR/force-warns-cap-lints-allow.rs:6:25
- |
-LL | pub fn function(_x: Box<SomeTrait>) {}
- | ^^^^^^^^^ help: use `dyn`: `dyn SomeTrait`
- |
- = note: requested on the command line with `--force-warns bare-trait-objects`
- = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
- = note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
-
-warning: 1 warning emitted
-
--- /dev/null
+// check-pass
+// Tests that we properly lint at 'paren' expressions
+
+fn foo() -> Result<(), String> {
+ (try!(Ok::<u8, String>(1))); //~ WARN use of deprecated macro `try`
+ Ok(())
+}
+
+fn main() {}
--- /dev/null
+warning: use of deprecated macro `try`: use the `?` operator instead
+ --> $DIR/issue-87274-paren-parent.rs:5:6
+ |
+LL | (try!(Ok::<u8, String>(1)));
+ | ^^^
+ |
+ = note: `#[warn(deprecated)]` on by default
+
+warning: 1 warning emitted
+
//~| HELP did you mean
//~| SUGGESTION dead_code
+#![deny(rust_2018_idiots)] //~ ERROR unknown lint
+ //~| HELP did you mean
+ //~| SUGGESTION rust_2018_idioms
+
fn main() {}
LL | #![deny(dead_cod)]
| ^^^^^^^^ help: did you mean: `dead_code`
-error: aborting due to 2 previous errors
+error: unknown lint: `rust_2018_idiots`
+ --> $DIR/lint-unknown-lint.rs:9:9
+ |
+LL | #![deny(rust_2018_idiots)]
+ | ^^^^^^^^^^^^^^^^ help: did you mean: `rust_2018_idioms`
+
+error: aborting due to 3 previous errors
#[my_macro]
fn use_bang_macro_as_attr() {}
-#[derive(Debug)] //~ ERROR `derive` may only be applied to structs
+#[derive(Debug)] //~ ERROR `derive` may only be applied to `struct`s
fn use_derive_macro_as_attr() {}
|
= note: this error originates in the macro `pat_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
--> $DIR/trace_faulty_macros.rs:42:1
|
LL | #[derive(Debug)]
- | ^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^ not applicable here
+LL | fn use_derive_macro_as_attr() {}
+ | -------------------------------- not a `struct`, `enum` or `union`
note: trace_macro
--> $DIR/trace_faulty_macros.rs:36:13
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
-error[E0658]: type alias impl trait is not permitted here
- --> $DIR/issue-75053.rs:52:15
+error: fatal error triggered by #[rustc_error]
+ --> $DIR/issue-75053.rs:49:1
|
-LL | let _pos: Phantom1<DummyT<()>> = Scope::new().my_index();
- | ^^^^^^^^^^^^^^^^^^^^
- |
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
- = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
+LL | fn main() {
+ | ^^^^^^^^^
error: aborting due to previous error; 1 warning emitted
-For more information about this error, try `rustc --explain E0658`.
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
+error[E0557]: feature has been removed
--> $DIR/issue-75053.rs:7:34
|
LL | #![cfg_attr(in_bindings, feature(impl_trait_in_bindings))]
- | ^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^ feature has been removed
|
- = note: `#[warn(incomplete_features)]` on by default
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
+ = note: removed due to being incomplete and unstable
-error[E0282]: type annotations needed
- --> $DIR/issue-75053.rs:52:38
- |
-LL | type O;
- | ------- `<Self as MyIndex<T>>::O` defined here
-...
-LL | let _pos: Phantom1<DummyT<()>> = Scope::new().my_index();
- | ^^^^^^^^^^-------------
- | |
- | this method call resolves to `<Self as MyIndex<T>>::O`
- | cannot infer type for type parameter `T`
-
-error: aborting due to previous error; 1 warning emitted
+error: aborting due to previous error
-For more information about this error, try `rustc --explain E0282`.
+For more information about this error, try `rustc --explain E0557`.
-error[E0658]: type alias impl trait is not permitted here
- --> $DIR/issue-75053.rs:52:15
+error: fatal error triggered by #[rustc_error]
+ --> $DIR/issue-75053.rs:49:1
|
-LL | let _pos: Phantom1<DummyT<()>> = Scope::new().my_index();
- | ^^^^^^^^^^^^^^^^^^^^
- |
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
- = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
+LL | fn main() {
+ | ^^^^^^^^^
error: aborting due to previous error
-For more information about this error, try `rustc --explain E0658`.
// compile-flags: -Z mir-opt-level=3
-// revisions: min_tait full_tait in_bindings
+// revisions: min_tait full_tait
#![feature(min_type_alias_impl_trait, rustc_attrs)]
#![cfg_attr(full_tait, feature(type_alias_impl_trait))]
//[full_tait]~^ WARN incomplete
-#![cfg_attr(in_bindings, feature(impl_trait_in_bindings))]
-//[in_bindings]~^ WARN incomplete
use std::marker::PhantomData;
#[rustc_error]
fn main() {
+ //~^ ERROR
let _pos: Phantom1<DummyT<()>> = Scope::new().my_index();
- //[min_tait,full_tait]~^ ERROR not permitted here
- //[in_bindings]~^^ ERROR type annotations needed
}
error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
--> $DIR/multiple-impls.rs:33:18
|
-LL | fn index(&self, index: Idx) -> &Self::Output;
- | --------------------------------------------- required by `Index::index`
-...
LL | Index::index(&[] as &[i32], 2u32);
| ^^^^^^^^^^^^^ trait message
|
= help: the trait `Index<u32>` is not implemented for `[i32]`
+note: required by `Index::index`
+ --> $DIR/multiple-impls.rs:12:5
+ |
+LL | fn index(&self, index: Idx) -> &Self::Output;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
--> $DIR/multiple-impls.rs:36:18
|
-LL | fn index(&self, index: Idx) -> &Self::Output;
- | --------------------------------------------- required by `Index::index`
-...
LL | Index::index(&[] as &[i32], Foo(2u32));
| ^^^^^^^^^^^^^ on impl for Foo
|
= help: the trait `Index<Foo<u32>>` is not implemented for `[i32]`
+note: required by `Index::index`
+ --> $DIR/multiple-impls.rs:12:5
+ |
+LL | fn index(&self, index: Idx) -> &Self::Output;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
--> $DIR/multiple-impls.rs:39:18
|
-LL | fn index(&self, index: Idx) -> &Self::Output;
- | --------------------------------------------- required by `Index::index`
-...
LL | Index::index(&[] as &[i32], Bar(2u32));
| ^^^^^^^^^^^^^ on impl for Bar
|
= help: the trait `Index<Bar<u32>>` is not implemented for `[i32]`
+note: required by `Index::index`
+ --> $DIR/multiple-impls.rs:12:5
+ |
+LL | fn index(&self, index: Idx) -> &Self::Output;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
--> $DIR/multiple-impls.rs:33:5
error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
--> $DIR/on-impl.rs:22:25
|
-LL | fn index(&self, index: Idx) -> &Self::Output;
- | --------------------------------------------- required by `Index::index`
-...
LL | Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32);
| ^^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice
|
= help: the trait `Index<u32>` is not implemented for `[i32]`
+note: required by `Index::index`
+ --> $DIR/on-impl.rs:9:5
+ |
+LL | fn index(&self, index: Idx) -> &Self::Output;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
--> $DIR/on-impl.rs:22:5
|
= help: the trait `Iterator` is not implemented for `bool`
= note: required because of the requirements on the impl of `IntoIterator` for `bool`
- = note: required by `into_iter`
+note: required by `into_iter`
+ --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+ |
+LL | fn into_iter(self) -> Self::IntoIter;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
+++ /dev/null
-#![feature(impl_trait_in_bindings)]
-#![allow(incomplete_features)]
-
-fn main() {
- const C: impl Copy = 0;
- match C {
- C | //~ ERROR: `impl Copy` cannot be used in patterns
- _ => {}
- }
-}
+++ /dev/null
-error: `impl Copy` cannot be used in patterns
- --> $DIR/issue-71042-opaquely-typed-constant-used-in-pattern.rs:7:9
- |
-LL | C |
- | ^
-
-error: aborting due to previous error
-
error[E0624]: associated function `bar` is private
--> $DIR/privacy1.rs:77:23
|
+LL | fn bar() {}
+ | -------- private associated function defined here
+...
LL | self::baz::A::bar();
| ^^^ private associated function
error[E0624]: associated function `bar` is private
--> $DIR/privacy1.rs:95:13
|
+LL | fn bar() {}
+ | -------- private associated function defined here
+...
LL | bar::A::bar();
| ^^^ private associated function
error[E0624]: associated function `bar` is private
--> $DIR/privacy1.rs:102:19
|
+LL | fn bar() {}
+ | -------- private associated function defined here
+...
LL | ::bar::A::bar();
| ^^^ private associated function
error[E0624]: associated function `bar` is private
--> $DIR/privacy1.rs:105:24
|
+LL | fn bar() {}
+ | -------- private associated function defined here
+...
LL | ::bar::baz::A::bar();
| ^^^ private associated function
error[E0624]: associated function `bar2` is private
--> $DIR/privacy1.rs:108:23
|
+LL | fn bar2(&self) {}
+ | -------------- private associated function defined here
+...
LL | ::bar::baz::A.bar2();
| ^^^^ private associated function
error[E0624]: associated function `foo` is private
--> $DIR/private-impl-method.rs:20:7
|
+LL | fn foo(&self) {}
+ | ------------- private associated function defined here
+...
LL | s.foo();
| ^^^ private associated function
|
LL | nyan.nap();
| ^^^ private associated function
+ |
+ ::: $DIR/auxiliary/cci_class_5.rs:8:9
+ |
+LL | fn nap(&self) {}
+ | ------------- private associated function defined here
error: aborting due to previous error
error[E0624]: associated function `f` is private
--> $DIR/private-method-inherited.rs:13:7
|
+LL | fn f(self) {}
+ | ---------- private associated function defined here
+...
LL | x.f();
| ^ private associated function
error[E0624]: associated function `nap` is private
--> $DIR/private-method.rs:22:8
|
+LL | fn nap(&self) {}
+ | ------------- private associated function defined here
+...
LL | nyan.nap();
| ^^^ private associated function
error[E0624]: associated function `f` is private
--> $DIR/test.rs:32:18
|
+LL | pub(super) fn f(&self) {}
+ | ---------------------- private associated function defined here
+...
LL | S::default().f();
| ^ private associated function
error[E0624]: associated function `g` is private
--> $DIR/test.rs:33:8
|
+LL | pub(super) fn g() {}
+ | ----------------- private associated function defined here
+...
LL | S::g();
| ^ private associated function
|
LL | u.g();
| ^ private associated function
+ |
+ ::: $DIR/auxiliary/pub_restricted.rs:14:5
+ |
+LL | pub(crate) fn g(&self) {}
+ | ---------------------- private associated function defined here
error[E0624]: associated function `h` is private
--> $DIR/test.rs:46:7
|
LL | u.h();
| ^ private associated function
+ |
+ ::: $DIR/auxiliary/pub_restricted.rs:15:5
+ |
+LL | crate fn h(&self) {}
+ | ----------------- private associated function defined here
error: aborting due to 12 previous errors
struct Y;
type A = X; //~ ERROR cannot find type `X` in this scope
-#[derive(Copy)] //~ ERROR `derive` may only be applied to structs, enums and unions
+#[derive(Copy)] //~ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s
mod n {}
#[empty_attr]
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
--> $DIR/attributes-on-modules-fail.rs:16:1
|
LL | #[derive(Copy)]
- | ^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^ not applicable here
+LL | mod n {}
+ | -------- not a `struct`, `enum` or `union`
error[E0658]: non-inline modules in proc macro input are unstable
--> $DIR/attributes-on-modules-fail.rs:20:1
extern "C" {
- #[derive(Copy)] //~ ERROR `derive` may only be applied to structs, enums and unions
+ #[derive(Copy)] //~ ERROR `derive` may only be applied to `struct`s, `enum`s and `union`s
fn f();
}
-error[E0774]: `derive` may only be applied to structs, enums and unions
+error[E0774]: `derive` may only be applied to `struct`s, `enum`s and `union`s
--> $DIR/macros-in-extern-derive.rs:2:5
|
LL | #[derive(Copy)]
- | ^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^ not applicable here
+LL | fn f();
+ | ------- not a `struct`, `enum` or `union`
error: aborting due to previous error
::: $DIR/span-from-proc-macro.rs:8:1
|
LL | #[error_from_attribute]
- | ----------------------- in this macro invocation
+ | ----------------------- in this procedural macro expansion
error[E0412]: cannot find type `OtherMissingType` in this scope
--> $DIR/auxiliary/span-from-proc-macro.rs:46:21
::: $DIR/span-from-proc-macro.rs:11:10
|
LL | #[derive(ErrorFromDerive)]
- | --------------- in this macro invocation
+ | --------------- in this derive macro expansion
error[E0425]: cannot find value `my_ident` in this scope
--> $DIR/auxiliary/span-from-proc-macro.rs:29:9
|
= note: required because of the requirements on the impl of `Iterator` for `std::ops::Range<bool>`
= note: required because of the requirements on the impl of `IntoIterator` for `std::ops::Range<bool>`
- = note: required by `into_iter`
+note: required by `into_iter`
+ --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+ |
+LL | fn into_iter(self) -> Self::IntoIter;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the size for values of type `[{integer}]` cannot be known at compilation time
--> $DIR/range-1.rs:14:17
error[E0277]: can't compare `std::ops::Range<usize>` with `std::ops::Range<usize>`
--> $DIR/range_traits-1.rs:5:5
|
+LL | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+ | ---------- in this derive macro expansion
+LL | struct AllTheRanges {
LL | a: Range<usize>,
| ^^^^^^^^^^^^^^^ no implementation for `std::ops::Range<usize> < std::ops::Range<usize>` and `std::ops::Range<usize> > std::ops::Range<usize>`
|
= help: the trait `PartialOrd` is not implemented for `std::ops::Range<usize>`
- = note: required by `std::cmp::PartialOrd::partial_cmp`
+note: required by `std::cmp::PartialOrd::partial_cmp`
+ --> $SRC_DIR/core/src/cmp.rs:LL:COL
+ |
+LL | fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: can't compare `std::ops::RangeTo<usize>` with `std::ops::RangeTo<usize>`
--> $DIR/range_traits-1.rs:8:5
|
+LL | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+ | ---------- in this derive macro expansion
+...
LL | b: RangeTo<usize>,
| ^^^^^^^^^^^^^^^^^ no implementation for `std::ops::RangeTo<usize> < std::ops::RangeTo<usize>` and `std::ops::RangeTo<usize> > std::ops::RangeTo<usize>`
|
= help: the trait `PartialOrd` is not implemented for `std::ops::RangeTo<usize>`
- = note: required by `std::cmp::PartialOrd::partial_cmp`
+note: required by `std::cmp::PartialOrd::partial_cmp`
+ --> $SRC_DIR/core/src/cmp.rs:LL:COL
+ |
+LL | fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: can't compare `std::ops::RangeFrom<usize>` with `std::ops::RangeFrom<usize>`
--> $DIR/range_traits-1.rs:11:5
|
+LL | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+ | ---------- in this derive macro expansion
+...
LL | c: RangeFrom<usize>,
| ^^^^^^^^^^^^^^^^^^^ no implementation for `std::ops::RangeFrom<usize> < std::ops::RangeFrom<usize>` and `std::ops::RangeFrom<usize> > std::ops::RangeFrom<usize>`
|
= help: the trait `PartialOrd` is not implemented for `std::ops::RangeFrom<usize>`
- = note: required by `std::cmp::PartialOrd::partial_cmp`
+note: required by `std::cmp::PartialOrd::partial_cmp`
+ --> $SRC_DIR/core/src/cmp.rs:LL:COL
+ |
+LL | fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: can't compare `std::ops::RangeFull` with `std::ops::RangeFull`
--> $DIR/range_traits-1.rs:14:5
|
+LL | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+ | ---------- in this derive macro expansion
+...
LL | d: RangeFull,
| ^^^^^^^^^^^^ no implementation for `std::ops::RangeFull < std::ops::RangeFull` and `std::ops::RangeFull > std::ops::RangeFull`
|
= help: the trait `PartialOrd` is not implemented for `std::ops::RangeFull`
- = note: required by `std::cmp::PartialOrd::partial_cmp`
+note: required by `std::cmp::PartialOrd::partial_cmp`
+ --> $SRC_DIR/core/src/cmp.rs:LL:COL
+ |
+LL | fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: can't compare `std::ops::RangeInclusive<usize>` with `std::ops::RangeInclusive<usize>`
--> $DIR/range_traits-1.rs:17:5
|
+LL | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+ | ---------- in this derive macro expansion
+...
LL | e: RangeInclusive<usize>,
| ^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `std::ops::RangeInclusive<usize> < std::ops::RangeInclusive<usize>` and `std::ops::RangeInclusive<usize> > std::ops::RangeInclusive<usize>`
|
= help: the trait `PartialOrd` is not implemented for `std::ops::RangeInclusive<usize>`
- = note: required by `std::cmp::PartialOrd::partial_cmp`
+note: required by `std::cmp::PartialOrd::partial_cmp`
+ --> $SRC_DIR/core/src/cmp.rs:LL:COL
+ |
+LL | fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: can't compare `std::ops::RangeToInclusive<usize>` with `std::ops::RangeToInclusive<usize>`
--> $DIR/range_traits-1.rs:20:5
|
+LL | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+ | ---------- in this derive macro expansion
+...
LL | f: RangeToInclusive<usize>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `std::ops::RangeToInclusive<usize> < std::ops::RangeToInclusive<usize>` and `std::ops::RangeToInclusive<usize> > std::ops::RangeToInclusive<usize>`
|
= help: the trait `PartialOrd` is not implemented for `std::ops::RangeToInclusive<usize>`
- = note: required by `std::cmp::PartialOrd::partial_cmp`
+note: required by `std::cmp::PartialOrd::partial_cmp`
+ --> $SRC_DIR/core/src/cmp.rs:LL:COL
+ |
+LL | fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `std::ops::Range<usize>: Ord` is not satisfied
--> $DIR/range_traits-1.rs:5:5
|
+LL | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+ | --- in this derive macro expansion
+LL | struct AllTheRanges {
LL | a: Range<usize>,
| ^^^^^^^^^^^^^^^ the trait `Ord` is not implemented for `std::ops::Range<usize>`
|
- = note: required by `std::cmp::Ord::cmp`
+note: required by `std::cmp::Ord::cmp`
+ --> $SRC_DIR/core/src/cmp.rs:LL:COL
+ |
+LL | fn cmp(&self, other: &Self) -> Ordering;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `std::ops::RangeTo<usize>: Ord` is not satisfied
--> $DIR/range_traits-1.rs:8:5
|
+LL | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+ | --- in this derive macro expansion
+...
LL | b: RangeTo<usize>,
| ^^^^^^^^^^^^^^^^^ the trait `Ord` is not implemented for `std::ops::RangeTo<usize>`
|
- = note: required by `std::cmp::Ord::cmp`
+note: required by `std::cmp::Ord::cmp`
+ --> $SRC_DIR/core/src/cmp.rs:LL:COL
+ |
+LL | fn cmp(&self, other: &Self) -> Ordering;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `std::ops::RangeFrom<usize>: Ord` is not satisfied
--> $DIR/range_traits-1.rs:11:5
|
+LL | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+ | --- in this derive macro expansion
+...
LL | c: RangeFrom<usize>,
| ^^^^^^^^^^^^^^^^^^^ the trait `Ord` is not implemented for `std::ops::RangeFrom<usize>`
|
- = note: required by `std::cmp::Ord::cmp`
+note: required by `std::cmp::Ord::cmp`
+ --> $SRC_DIR/core/src/cmp.rs:LL:COL
+ |
+LL | fn cmp(&self, other: &Self) -> Ordering;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `std::ops::RangeFull: Ord` is not satisfied
--> $DIR/range_traits-1.rs:14:5
|
+LL | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+ | --- in this derive macro expansion
+...
LL | d: RangeFull,
| ^^^^^^^^^^^^ the trait `Ord` is not implemented for `std::ops::RangeFull`
|
- = note: required by `std::cmp::Ord::cmp`
+note: required by `std::cmp::Ord::cmp`
+ --> $SRC_DIR/core/src/cmp.rs:LL:COL
+ |
+LL | fn cmp(&self, other: &Self) -> Ordering;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `std::ops::RangeInclusive<usize>: Ord` is not satisfied
--> $DIR/range_traits-1.rs:17:5
|
+LL | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+ | --- in this derive macro expansion
+...
LL | e: RangeInclusive<usize>,
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Ord` is not implemented for `std::ops::RangeInclusive<usize>`
|
- = note: required by `std::cmp::Ord::cmp`
+note: required by `std::cmp::Ord::cmp`
+ --> $SRC_DIR/core/src/cmp.rs:LL:COL
+ |
+LL | fn cmp(&self, other: &Self) -> Ordering;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0277]: the trait bound `std::ops::RangeToInclusive<usize>: Ord` is not satisfied
--> $DIR/range_traits-1.rs:20:5
|
+LL | #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+ | --- in this derive macro expansion
+...
LL | f: RangeToInclusive<usize>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Ord` is not implemented for `std::ops::RangeToInclusive<usize>`
|
- = note: required by `std::cmp::Ord::cmp`
+note: required by `std::cmp::Ord::cmp`
+ --> $SRC_DIR/core/src/cmp.rs:LL:COL
+ |
+LL | fn cmp(&self, other: &Self) -> Ordering;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 12 previous errors
error[E0277]: `main` has invalid return type `Result<f32, ParseFloatError>`
--> $DIR/termination-trait-test-wrong-type.rs:6:1
|
+LL | #[test]
+ | ------- in this procedural macro expansion
LL | / fn can_parse_zero_as_f32() -> Result<f32, ParseFloatError> {
LL | | "0".parse()
LL | | }
| ^^^^^^^^^^^^ the `?` operator cannot be applied to type `bool`
|
= help: the trait `Try` is not implemented for `bool`
- = note: required by `branch`
+note: required by `branch`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
--> $DIR/disallowed-positions.rs:46:19
| |_- this function should return `Result` or `Option` to accept `?`
|
= help: the trait `FromResidual<_>` is not implemented for `()`
- = note: required by `from_residual`
+note: required by `from_residual`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn from_residual(residual: R) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0308]: mismatched types
--> $DIR/disallowed-positions.rs:56:8
| ^^ the `?` operator cannot be applied to type `{integer}`
|
= help: the trait `Try` is not implemented for `{integer}`
- = note: required by `branch`
+note: required by `branch`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0308]: mismatched types
--> $DIR/disallowed-positions.rs:96:11
| ^^^^^^^^^^^^ the `?` operator cannot be applied to type `bool`
|
= help: the trait `Try` is not implemented for `bool`
- = note: required by `branch`
+note: required by `branch`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
--> $DIR/disallowed-positions.rs:110:22
| |_- this function should return `Result` or `Option` to accept `?`
|
= help: the trait `FromResidual<_>` is not implemented for `()`
- = note: required by `from_residual`
+note: required by `from_residual`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn from_residual(residual: R) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0308]: mismatched types
--> $DIR/disallowed-positions.rs:120:11
| ^^ the `?` operator cannot be applied to type `{integer}`
|
= help: the trait `Try` is not implemented for `{integer}`
- = note: required by `branch`
+note: required by `branch`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0614]: type `bool` cannot be dereferenced
--> $DIR/disallowed-positions.rs:173:5
| ^^^^^^^^^^^^ the `?` operator cannot be applied to type `bool`
|
= help: the trait `Try` is not implemented for `bool`
- = note: required by `branch`
+note: required by `branch`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
--> $DIR/disallowed-positions.rs:183:16
| |_- this function should return `Result` or `Option` to accept `?`
|
= help: the trait `FromResidual<_>` is not implemented for `()`
- = note: required by `from_residual`
+note: required by `from_residual`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn from_residual(residual: R) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0308]: mismatched types
--> $DIR/disallowed-positions.rs:198:10
| ^^ the `?` operator cannot be applied to type `{integer}`
|
= help: the trait `Try` is not implemented for `{integer}`
- = note: required by `branch`
+note: required by `branch`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 104 previous errors; 2 warnings emitted
--- /dev/null
+// check-pass
+#![feature(const_fn_trait_bound)]
+#![feature(const_trait_impl)]
+
+trait MyPartialEq {
+ fn eq(&self, other: &Self) -> bool;
+}
+
+impl<T: PartialEq> const MyPartialEq for T {
+ fn eq(&self, other: &Self) -> bool {
+ PartialEq::eq(self, other)
+ }
+}
+
+fn main() {}
help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a bound
|
LL | async fn f(self: Pin<&Self>) -> impl Clone + '_ { self }
- | ^^^^^^^^^^^^^^^
+ | ^^^^
error: aborting due to previous error
help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a bound
|
LL | fn f(self: Pin<&Self>) -> impl Clone + '_ { self }
- | ^^^^^^^^^^^^^^^
+ | ^^^^
error: aborting due to previous error
error[E0277]: the trait bound `u8: Tr` is not satisfied
--> $DIR/issue-29595.rs:6:17
|
-LL | const C: Self;
- | -------------- required by `Tr::C`
-...
LL | let a: u8 = Tr::C;
| ^^^^^ the trait `Tr` is not implemented for `u8`
+ |
+note: required by `Tr::C`
+ --> $DIR/issue-29595.rs:2:5
+ |
+LL | const C: Self;
+ | ^^^^^^^^^^^^^^
error: aborting due to previous error
error[E0624]: associated function `new` is private
--> $DIR/static-method-privacy.rs:9:19
|
+LL | fn new() -> S { S }
+ | ------------- private associated function defined here
+...
LL | let _ = a::S::new();
| ^^^ private associated function
error[E0277]: the trait bound `NoClone: Clone` is not satisfied
--> $DIR/struct-path-alias-bounds.rs:9:13
|
-LL | struct S<T: Clone> { a: T }
- | ------------------ required by `S`
-...
LL | let s = A { a: NoClone };
| ^ the trait `Clone` is not implemented for `NoClone`
+ |
+note: required by `S`
+ --> $DIR/struct-path-alias-bounds.rs:3:1
+ |
+LL | struct S<T: Clone> { a: T }
+ | ^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
| ^^^^^^^^ the trait `Unpin` is not implemented for `dyn Future<Output = i32> + Send`
|
= note: consider using `Box::pin`
- = note: required by `Pin::<P>::new`
+note: required by `Pin::<P>::new`
+ --> $SRC_DIR/core/src/pin.rs:LL:COL
+ |
+LL | pub const fn new(pointer: P) -> Pin<P> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: `dyn Future<Output = i32> + Send` cannot be unpinned
--> $DIR/expected-boxed-future-isnt-pinned.rs:27:5
| ^^^^^^^^ the trait `Unpin` is not implemented for `dyn Future<Output = i32> + Send`
|
= note: consider using `Box::pin`
- = note: required by `Pin::<P>::new`
+note: required by `Pin::<P>::new`
+ --> $SRC_DIR/core/src/pin.rs:LL:COL
+ |
+LL | pub const fn new(pointer: P) -> Pin<P> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0308]: mismatched types
--> $DIR/expected-boxed-future-isnt-pinned.rs:31:5
| ^^^^^^^^^^^^^^^^^^ the `?` operator cannot be applied to type `impl Future`
|
= help: the trait `Try` is not implemented for `impl Future`
- = note: required by `branch`
+note: required by `branch`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: consider `await`ing on the `Future`
|
LL | SadGirl {}.call().await?;
| |
| expected an implementor of trait `SomeTrait`
| help: consider borrowing here: `&f`
-...
+ |
+note: required by `Other::<'a, G>::new`
+ --> $DIR/issue-84973.rs:27:5
+ |
LL | pub fn new(g: G) -> Self {
- | ------------------------ required by `Other::<'a, G>::new`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a bound
|
LL | fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> + '_ {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^
error: lifetime may not live long enough
--> $DIR/trait-object-nested-in-impl-trait.rs:39:9
help: to allow this `impl Trait` to capture borrowed data with lifetime `'a`, add `'a` as a bound
|
LL | fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> + 'a {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^
error: aborting due to 4 previous errors
| ^^ the trait `std::io::Write` is not implemented for `&dyn std::io::Write`
|
= note: `std::io::Write` is implemented for `&mut dyn std::io::Write`, but not for `&dyn std::io::Write`
- = note: required by `BufWriter::<W>::new`
+note: required by `BufWriter::<W>::new`
+ --> $SRC_DIR/std/src/io/buffered/bufwriter.rs:LL:COL
+ |
+LL | pub fn new(inner: W) -> BufWriter<W> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied
--> $DIR/mut-borrow-needed-by-trait.rs:17:14
error[E0038]: the trait `Trait` cannot be made into an object
- --> $DIR/object-unsafe-trait-references-self.rs:6:11
+ --> $DIR/object-unsafe-trait-references-self.rs:6:12
|
LL | fn bar(x: &dyn Trait) {}
- | ^^^^^^^^^^ `Trait` cannot be made into an object
+ | ^^^^^^^^^ `Trait` cannot be made into an object
|
= help: consider moving `baz` to another trait
= help: consider moving `bat` to another trait
| ^^^^ ...because method `bat` references the `Self` type in its return type
error[E0038]: the trait `Other` cannot be made into an object
- --> $DIR/object-unsafe-trait-references-self.rs:10:11
+ --> $DIR/object-unsafe-trait-references-self.rs:10:12
|
LL | fn foo(x: &dyn Other) {}
- | ^^^^^^^^^^ `Other` cannot be made into an object
+ | ^^^^^^^^^ `Other` 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/object-unsafe-trait-references-self.rs:8:14
error[E0038]: the trait `Trait` cannot be made into an object
- --> $DIR/object-unsafe-trait-should-use-where-sized.rs:9:11
+ --> $DIR/object-unsafe-trait-should-use-where-sized.rs:9:12
|
LL | fn bar(x: &dyn Trait) {}
- | ^^^^^^^^^^ `Trait` cannot be made into an object
+ | ^^^^^^^^^ `Trait` 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/object-unsafe-trait-should-use-where-sized.rs:5:8
LL | let mut stream_reader = BufReader::new(&stream);
| ^^^^^^^ the trait `std::io::Read` is not implemented for `&T`
|
- = note: required by `BufReader::<R>::new`
+note: required by `BufReader::<R>::new`
+ --> $SRC_DIR/std/src/io/buffered/bufreader.rs:LL:COL
+ |
+LL | pub fn new(inner: R) -> BufReader<R> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: consider removing the leading `&`-reference
|
LL | let mut stream_reader = BufReader::new(stream);
|
= help: the trait `Iterator` is not implemented for `&Enumerate<std::slice::Iter<'_, {integer}>>`
= note: required because of the requirements on the impl of `IntoIterator` for `&Enumerate<std::slice::Iter<'_, {integer}>>`
- = note: required by `into_iter`
+note: required by `into_iter`
+ --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+ |
+LL | fn into_iter(self) -> Self::IntoIter;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
|
= help: the trait `Iterator` is not implemented for `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>`
= note: required because of the requirements on the impl of `IntoIterator` for `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>`
- = note: required by `into_iter`
+note: required by `into_iter`
+ --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+ |
+LL | fn into_iter(self) -> Self::IntoIter;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
|
= help: the trait `Iterator` is not implemented for `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>`
= note: required because of the requirements on the impl of `IntoIterator` for `&&&&&Enumerate<std::slice::Iter<'_, {integer}>>`
- = note: required by `into_iter`
+note: required by `into_iter`
+ --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+ |
+LL | fn into_iter(self) -> Self::IntoIter;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
| ^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `dyn Trait`
- = note: required by `Vec::<T>::new`
+note: required by `Vec::<T>::new`
+ --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
+ |
+LL | pub const fn new() -> Self {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time
--> $DIR/bad-sized.rs:4:37
error[E0277]: the trait bound `{integer}: Trait` is not satisfied
--> $DIR/on-structs-and-enums-locals.rs:10:15
|
-LL | struct Foo<T:Trait> {
- | ------------------- required by `Foo`
-...
LL | let foo = Foo {
| ^^^ the trait `Trait` is not implemented for `{integer}`
+ |
+note: required by `Foo`
+ --> $DIR/on-structs-and-enums-locals.rs:5:1
+ |
+LL | struct Foo<T:Trait> {
+ | ^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
LL | let foo = Foo {
| ^^^ the trait `Trait` is not implemented for `{integer}`
|
- = note: required by `Foo`
+note: required by `Foo`
+ --> $DIR/auxiliary/on_structs_and_enums_xc.rs:5:1
+ |
+LL | pub struct Foo<T:Trait> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
error[E0275]: overflow evaluating the requirement `SalsaStorage: RefUnwindSafe`
--> $DIR/cycle-cache-err-60010.rs:69:5
|
-LL | fn parse(&self) {
- | --------------- required by `SourceDatabase::parse`
-...
LL | SourceDatabase::parse(db);
| ^^^^^^^^^^^^^^^^^^^^^
|
|
LL | impl<T> SourceDatabase for T
| ^^^^^^^^^^^^^^ ^
+note: required by `SourceDatabase::parse`
+ --> $DIR/cycle-cache-err-60010.rs:14:5
+ |
+LL | fn parse(&self) {
+ | ^^^^^^^^^^^^^^^
error: aborting due to previous error
error[E0277]: the trait bound `dyn CompareToInts: CompareTo<i32>` is not satisfied
--> $DIR/repeated-supertrait-ambig.rs:34:5
|
-LL | fn same_as(&self, t: T) -> bool;
- | -------------------------------- required by `CompareTo::same_as`
-...
LL | <dyn CompareToInts>::same_as(c, 22)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `CompareTo<i32>` is not implemented for `dyn CompareToInts`
+ |
+note: required by `CompareTo::same_as`
+ --> $DIR/repeated-supertrait-ambig.rs:9:5
+ |
+LL | fn same_as(&self, t: T) -> bool;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the trait bound `C: CompareTo<i32>` is not satisfied
--> $DIR/repeated-supertrait-ambig.rs:38:5
|
-LL | fn same_as(&self, t: T) -> bool;
- | -------------------------------- required by `CompareTo::same_as`
-...
LL | CompareTo::same_as(c, 22)
| ^^^^^^^^^^^^^^^^^^ the trait `CompareTo<i32>` is not implemented for `C`
|
+note: required by `CompareTo::same_as`
+ --> $DIR/repeated-supertrait-ambig.rs:9:5
+ |
+LL | fn same_as(&self, t: T) -> bool;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: consider further restricting this bound
|
LL | fn with_ufcs2<C:CompareToInts + CompareTo<i32>>(c: &C) -> bool {
error[E0277]: the trait bound `Foo: Clone` is not satisfied
--> $DIR/issue-71136.rs:5:5
|
+LL | #[derive(Clone)]
+ | ----- in this derive macro expansion
+LL | struct FooHolster {
LL | the_foos: Vec<Foo>,
| ^^^^^^^^^^^^^^^^^^ expected an implementor of trait `Clone`
|
= note: required because of the requirements on the impl of `Clone` for `Vec<Foo>`
- = note: required by `clone`
+note: required by `clone`
+ --> $SRC_DIR/core/src/clone.rs:LL:COL
+ |
+LL | fn clone(&self) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
| cannot infer type for type parameter `T` declared on the trait `From`
|
= note: cannot satisfy `u32: From<_>`
- = note: required by `from`
+note: required by `from`
+ --> $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ |
+LL | fn from(_: T) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^
error[E0283]: type annotations needed for `Box<T>`
--> $DIR/issue-77982.rs:35:16
error[E0277]: the trait bound `&mut T: Clone` is not satisfied
--> $DIR/issue-79458.rs:6:5
|
+LL | #[derive(Clone)]
+ | ----- in this derive macro expansion
+LL | struct Foo<'a, T> {
LL | bar: &'a mut T
| ^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `&mut T`
|
= help: the following implementations were found:
<&T as Clone>
= note: `Clone` is implemented for `&T`, but not for `&mut T`
- = note: required by `clone`
+note: required by `clone`
+ --> $SRC_DIR/core/src/clone.rs:LL:COL
+ |
+LL | fn clone(&self) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
error[E0624]: associated function `a` is private
--> $DIR/item-privacy.rs:72:7
|
+LL | fn a(&self) { }
+ | ----------- private associated function defined here
+...
LL | c.a();
| ^ private associated function
error[E0624]: associated function `a` is private
--> $DIR/item-privacy.rs:84:14
|
+LL | fn a(&self) { }
+ | ----------- private associated function defined here
+...
LL | <dyn C>::a(&S);
| ^ private associated function
error[E0624]: associated constant `A` is private
--> $DIR/item-privacy.rs:101:14
|
+LL | const A: u8 = 0;
+ | ---------------- private associated constant defined here
+...
LL | <dyn C>::A;
| ^ private associated constant
error[E0624]: associated function `method` is private
--> $DIR/method-private.rs:19:9
|
+LL | fn method(&self) {}
+ | ---------------- private associated function defined here
+...
LL | foo.method();
| ^^^^^^ private associated function
|
error[E0277]: `dummy::TestType` cannot be sent between threads safely
--> $DIR/negated-auto-traits-error.rs:23:11
|
-LL | struct Outer<T: Send>(T);
- | ------------------------- required by `Outer`
-...
LL | Outer(TestType);
| ^^^^^^^^ `dummy::TestType` cannot be sent between threads safely
|
= help: the trait `Send` is not implemented for `dummy::TestType`
+note: required by `Outer`
+ --> $DIR/negated-auto-traits-error.rs:10:1
+ |
+LL | struct Outer<T: Send>(T);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: `dummy::TestType` cannot be sent between threads safely
--> $DIR/negated-auto-traits-error.rs:23:5
error[E0277]: the trait bound `(): MyTrait` is not satisfied
--> $DIR/no-use.rs:10:26
|
-LL | trait MyTrait { fn foo(&self); }
- | -------------- required by `MyTrait::foo`
-...
LL | <() as MyTrait>::foo(&());
| ^^^ the trait `MyTrait` is not implemented for `()`
|
= help: the following implementations were found:
<() as MyTrait>
+note: required by `MyTrait::foo`
+ --> $DIR/no-use.rs:5:17
+ |
+LL | trait MyTrait { fn foo(&self); }
+ | ^^^^^^^^^^^^^^
error: aborting due to previous error
error[E0283]: type annotations needed
--> $DIR/static-method-generic-inference.rs:24:25
|
-LL | fn new() -> T;
- | -------------- required by `HasNew::new`
-...
LL | let _f: base::Foo = base::HasNew::new();
| ^^^^^^^^^^^^^^^^^ cannot infer type
|
= note: cannot satisfy `_: HasNew<Foo>`
+note: required by `HasNew::new`
+ --> $DIR/static-method-generic-inference.rs:8:9
+ |
+LL | fn new() -> T;
+ | ^^^^^^^^^^^^^^
error: aborting due to previous error
LL | <u64 as From<T>>::from;
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `From<T>` is not implemented for `u64`
|
- = note: required by `from`
+note: required by `from`
+ --> $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ |
+LL | fn from(_: T) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^
help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
|
LL | fn check<T: Iterator, U: ?Sized>() where u64: From<T> {
LL | <u64 as From<<T as Iterator>::Item>>::from;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<<T as Iterator>::Item>` is not implemented for `u64`
|
- = note: required by `from`
+note: required by `from`
+ --> $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ |
+LL | fn from(_: T) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^
help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
|
LL | fn check<T: Iterator, U: ?Sized>() where u64: From<<T as Iterator>::Item> {
LL | <Misc<_> as From<T>>::from;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<T>` is not implemented for `Misc<_>`
|
- = note: required by `from`
+note: required by `from`
+ --> $SRC_DIR/core/src/convert/mod.rs:LL:COL
+ |
+LL | fn from(_: T) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the size for values of type `[T]` cannot be known at compilation time
--> $DIR/suggest-where-clause.rs:28:20
error[E0277]: the trait bound `i32: Foo` is not satisfied
--> $DIR/trivial-bounds-leak.rs:25:15
|
-LL | fn test(&self);
- | --------------- required by `Foo::test`
-...
LL | Foo::test(&4i32);
| ^^^^^ the trait `Foo` is not implemented for `i32`
+ |
+note: required by `Foo::test`
+ --> $DIR/trivial-bounds-leak.rs:5:5
+ |
+LL | fn test(&self);
+ | ^^^^^^^^^^^^^^^
error[E0277]: the trait bound `i32: Foo` is not satisfied
--> $DIR/trivial-bounds-leak.rs:26:22
= help: the following implementations were found:
<TryFromSliceError as From<Infallible>>
= note: required because of the requirements on the impl of `FromResidual<Result<Infallible, &str>>` for `Result<u32, TryFromSliceError>`
- = note: required by `from_residual`
+note: required by `from_residual`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn from_residual(residual: R) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0271]: type mismatch resolving `<Result<i32, i32> as Try>::Output == &str`
--> $DIR/try-block-bad-type.rs:12:9
| ^ could not wrap the final value of the block as `()` doesn't implement `Try`
|
= help: the trait `Try` is not implemented for `()`
- = note: required by `from_output`
+note: required by `from_output`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn from_output(output: Self::Output) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: a `try` block must return `Result` or `Option` (or another type that implements `Try`)
--> $DIR/try-block-bad-type.rs:20:26
| ^ could not wrap the final value of the block as `i32` doesn't implement `Try`
|
= help: the trait `Try` is not implemented for `i32`
- = note: required by `from_output`
+note: required by `from_output`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn from_output(output: Self::Output) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 5 previous errors
| ^^^^^ could not wrap the final value of the block as `bool` doesn't implement `Try`
|
= help: the trait `Try` is not implemented for `bool`
- = note: required by `from_output`
+note: required by `from_output`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn from_output(output: Self::Output) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
<u8 as From<NonZeroU8>>
<u8 as From<bool>>
= note: required because of the requirements on the impl of `FromResidual<Result<Infallible, i32>>` for `Result<u64, u8>`
- = note: required by `from_residual`
+note: required by `from_residual`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn from_residual(residual: R) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the `?` operator can only be used on `Result`s, not `Option`s, in a function that returns `Result`
--> $DIR/bad-interconversion.rs:11:12
| |_- this function returns a `Result`
|
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `Result<u64, String>`
- = note: required by `from_residual`
+note: required by `from_residual`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn from_residual(residual: R) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the `?` operator can only be used on `Result`s in a function that returns `Result`
--> $DIR/bad-interconversion.rs:17:31
| |_- this function returns a `Result`
|
= help: the trait `FromResidual<ControlFlow<{integer}, Infallible>>` is not implemented for `Result<u64, String>`
- = note: required by `from_residual`
+note: required by `from_residual`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn from_residual(residual: R) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the `?` operator can only be used on `Option`s, not `Result`s, in a function that returns `Option`
--> $DIR/bad-interconversion.rs:22:22
| |_- this function returns an `Option`
|
= help: the trait `FromResidual<Result<Infallible, &str>>` is not implemented for `Option<u16>`
- = note: required by `from_residual`
+note: required by `from_residual`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn from_residual(residual: R) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the `?` operator can only be used on `Option`s in a function that returns `Option`
--> $DIR/bad-interconversion.rs:27:33
| |_- this function returns an `Option`
|
= help: the trait `FromResidual<ControlFlow<{integer}, Infallible>>` is not implemented for `Option<u64>`
- = note: required by `from_residual`
+note: required by `from_residual`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn from_residual(residual: R) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the `?` operator can only be used on `ControlFlow`s in a function that returns `ControlFlow`
--> $DIR/bad-interconversion.rs:32:39
| |_- this function returns a `ControlFlow`
|
= help: the trait `FromResidual<Result<Infallible, &str>>` is not implemented for `ControlFlow<String>`
- = note: required by `from_residual`
+note: required by `from_residual`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn from_residual(residual: R) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the `?` operator can only be used on `ControlFlow`s in a function that returns `ControlFlow`
--> $DIR/bad-interconversion.rs:37:12
| |_- this function returns a `ControlFlow`
|
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `ControlFlow<u64>`
- = note: required by `from_residual`
+note: required by `from_residual`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn from_residual(residual: R) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the `?` operator in a function that returns `ControlFlow<B, _>` can only be used on other `ControlFlow<B, _>`s (with the same Break type)
--> $DIR/bad-interconversion.rs:43:29
|
= help: the trait `FromResidual<ControlFlow<u8, Infallible>>` is not implemented for `ControlFlow<i64>`
= note: unlike `Result`, there's no `From`-conversion performed for `ControlFlow`
- = note: required by `from_residual`
+note: required by `from_residual`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn from_residual(residual: R) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 8 previous errors
| |_- this function returns a `Result`
|
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `Result<(), ()>`
- = note: required by `from_residual`
+note: required by `from_residual`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn from_residual(residual: R) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the `?` operator can only be used on `Option`s, not `Result`s, in a function that returns `Option`
--> $DIR/option-to-result.rs:11:6
| |_- this function returns an `Option`
|
= help: the trait `FromResidual<Result<Infallible, i32>>` is not implemented for `Option<i32>`
- = note: required by `from_residual`
+note: required by `from_residual`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn from_residual(residual: R) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
| |_- this function should return `Result` or `Option` to accept `?`
|
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `u32`
- = note: required by `from_residual`
+note: required by `from_residual`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn from_residual(residual: R) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the `?` operator can only be used in a closure that returns `Result` or `Option` (or another type that implements `FromResidual`)
--> $DIR/try-on-option-diagnostics.rs:14:10
| |_____- this function should return `Result` or `Option` to accept `?`
|
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `{integer}`
- = note: required by `from_residual`
+note: required by `from_residual`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn from_residual(residual: R) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the `?` operator can only be used in a method that returns `Result` or `Option` (or another type that implements `FromResidual`)
--> $DIR/try-on-option-diagnostics.rs:26:14
| |_________- this function should return `Result` or `Option` to accept `?`
|
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `()`
- = note: required by `from_residual`
+note: required by `from_residual`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn from_residual(residual: R) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the `?` operator can only be used in a trait method that returns `Result` or `Option` (or another type that implements `FromResidual`)
--> $DIR/try-on-option-diagnostics.rs:39:14
| |_________- this function should return `Result` or `Option` to accept `?`
|
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `()`
- = note: required by `from_residual`
+note: required by `from_residual`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn from_residual(residual: R) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 4 previous errors
| |_- this function returns a `Result`
|
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `Result<u32, ()>`
- = note: required by `from_residual`
+note: required by `from_residual`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn from_residual(residual: R) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
--> $DIR/try-on-option.rs:13:6
| |_- this function should return `Result` or `Option` to accept `?`
|
= help: the trait `FromResidual<Option<Infallible>>` is not implemented for `u32`
- = note: required by `from_residual`
+note: required by `from_residual`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn from_residual(residual: R) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
| |_- this function should return `Result` or `Option` to accept `?`
|
= help: the trait `FromResidual<Result<Infallible, std::io::Error>>` is not implemented for `()`
- = note: required by `from_residual`
+note: required by `from_residual`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn from_residual(residual: R) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the `?` operator can only be applied to values that implement `Try`
--> $DIR/try-operator-on-main.rs:10:5
| ^^^ the `?` operator cannot be applied to type `()`
|
= help: the trait `Try` is not implemented for `()`
- = note: required by `branch`
+note: required by `branch`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`)
--> $DIR/try-operator-on-main.rs:10:7
| |_- this function should return `Result` or `Option` to accept `?`
|
= help: the trait `FromResidual<_>` is not implemented for `()`
- = note: required by `from_residual`
+note: required by `from_residual`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn from_residual(residual: R) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the trait bound `(): Try` is not satisfied
--> $DIR/try-operator-on-main.rs:14:25
| ^^^ the `?` operator cannot be applied to type `()`
|
= help: the trait `Try` is not implemented for `()`
- = note: required by `branch`
+note: required by `branch`
+ --> $SRC_DIR/core/src/ops/try_trait.rs:LL:COL
+ |
+LL | fn branch(self) -> ControlFlow<Self::Residual, Self::Output>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 5 previous errors
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
+warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/issue-53096.rs:4:32
|
-LL | #![cfg_attr(full_tait, feature(impl_trait_in_bindings, type_alias_impl_trait))]
- | ^^^^^^^^^^^^^^^^^^^^^^
+LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))]
+ | ^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
-warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/issue-53096.rs:4:56
- |
-LL | #![cfg_attr(full_tait, feature(impl_trait_in_bindings, type_alias_impl_trait))]
- | ^^^^^^^^^^^^^^^^^^^^^
- |
= note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
error: fatal error triggered by #[rustc_error]
LL | fn main() {}
| ^^^^^^^^^
-error: aborting due to previous error; 2 warnings emitted
+error: aborting due to previous error; 1 warning emitted
-error[E0658]: type alias impl trait is not permitted here
- --> $DIR/issue-53096.rs:10:19
+error: fatal error triggered by #[rustc_error]
+ --> $DIR/issue-53096.rs:14:1
|
-LL | const BAZR: Foo = bar();
- | ^^^^^
- |
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
- = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
+LL | fn main() {}
+ | ^^^^^^^^^
error: aborting due to previous error
-For more information about this error, try `rustc --explain E0658`.
#![feature(const_impl_trait, const_fn_fn_ptr_basics, rustc_attrs)]
// revisions: min_tait full_tait
#![feature(min_type_alias_impl_trait)]
-#![cfg_attr(full_tait, feature(impl_trait_in_bindings, type_alias_impl_trait))]
+#![cfg_attr(full_tait, feature(type_alias_impl_trait))]
//[full_tait]~^ WARN incomplete
-//[full_tait]~| WARN incomplete
type Foo = impl Fn() -> usize;
-const fn bar() -> Foo { || 0usize }
+const fn bar() -> Foo {
+ || 0usize
+}
const BAZR: Foo = bar();
-//[min_tait]~^ ERROR not permitted here
#[rustc_error]
-fn main() {} //[full_tait]~ ERROR
+fn main() {} //~ ERROR
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
+warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/issue-53678-generator-and-const-fn.rs:4:32
|
-LL | #![cfg_attr(full_tait, feature(impl_trait_in_bindings, type_alias_impl_trait))]
- | ^^^^^^^^^^^^^^^^^^^^^^
+LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))]
+ | ^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
-warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/issue-53678-generator-and-const-fn.rs:4:56
- |
-LL | #![cfg_attr(full_tait, feature(impl_trait_in_bindings, type_alias_impl_trait))]
- | ^^^^^^^^^^^^^^^^^^^^^
- |
= note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
error: fatal error triggered by #[rustc_error]
- --> $DIR/issue-53678-generator-and-const-fn.rs:23:1
+ --> $DIR/issue-53678-generator-and-const-fn.rs:22:1
|
LL | fn main() {}
| ^^^^^^^^^
-error: aborting due to previous error; 2 warnings emitted
+error: aborting due to previous error; 1 warning emitted
-error[E0658]: type alias impl trait is not permitted here
- --> $DIR/issue-53678-generator-and-const-fn.rs:20:36
+error: fatal error triggered by #[rustc_error]
+ --> $DIR/issue-53678-generator-and-const-fn.rs:22:1
|
-LL | const FOO: GenOnce<usize, usize> = const_generator(10, 100);
- | ^^^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
- = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
+LL | fn main() {}
+ | ^^^^^^^^^
error: aborting due to previous error
-For more information about this error, try `rustc --explain E0658`.
#![feature(const_impl_trait, generators, generator_trait, rustc_attrs)]
// revisions: min_tait full_tait
#![feature(min_type_alias_impl_trait)]
-#![cfg_attr(full_tait, feature(impl_trait_in_bindings, type_alias_impl_trait))]
+#![cfg_attr(full_tait, feature(type_alias_impl_trait))]
//[full_tait]~^ WARN incomplete
-//[full_tait]~| WARN incomplete
use std::ops::Generator;
}
}
-const FOO: GenOnce<usize, usize> = const_generator(10, 100); //[min_tait]~ ERROR not permitted here
+const FOO: GenOnce<usize, usize> = const_generator(10, 100);
#[rustc_error]
-fn main() {} //[full_tait]~ ERROR
+fn main() {} //~ ERROR
= help: add `#![feature(min_type_alias_impl_trait)]` to the crate attributes to enable
error[E0658]: type alias impl trait is not permitted here
- --> $DIR/issue-60371.rs:14:37
+ --> $DIR/issue-60371.rs:14:40
|
LL | const FUN: fn() -> Self::Item = || ();
- | ^^^^^
+ | ^
|
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
- = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
+ = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
+ = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable
error[E0277]: the trait bound `(): Bug` is not satisfied
--> $DIR/issue-60371.rs:10:17
warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/issue-60407.rs:3:32
|
-LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
+LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))]
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/issue-60407.rs:3:55
- |
-LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
- | ^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
error: fatal error triggered by #[rustc_error]
- --> $DIR/issue-60407.rs:12:1
+ --> $DIR/issue-60407.rs:11:1
|
LL | fn main() {
| ^^^^^^^^^
-error: aborting due to previous error; 2 warnings emitted
+error: aborting due to previous error; 1 warning emitted
-error[E0658]: type alias impl trait is not permitted here
- --> $DIR/issue-60407.rs:9:39
+error: fatal error triggered by #[rustc_error]
+ --> $DIR/issue-60407.rs:11:1
|
-LL | static mut TEST: Option<Debuggable> = None;
- | ^^^^
- |
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
- = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
-
-error: concrete type differs from previous defining opaque type use
- --> $DIR/issue-60407.rs:16:1
- |
-LL | fn foo() -> Debuggable {
- | ^^^^^^^^^^^^^^^^^^^^^^ expected `[type error]`, got `u32`
- |
-note: previous use here
- --> $DIR/issue-60407.rs:9:1
- |
-LL | static mut TEST: Option<Debuggable> = None;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | fn main() {
+ | ^^^^^^^^^
-error: aborting due to 2 previous errors
+error: aborting due to previous error
-For more information about this error, try `rustc --explain E0658`.
// revisions: min_tait full_tait
#![feature(min_type_alias_impl_trait, rustc_attrs)]
-#![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
+#![cfg_attr(full_tait, feature(type_alias_impl_trait))]
//[full_tait]~^ WARN incomplete
-//[full_tait]~| WARN incomplete
type Debuggable = impl core::fmt::Debug;
-static mut TEST: Option<Debuggable> = None; //[min_tait]~ ERROR not permitted here
+static mut TEST: Option<Debuggable> = None;
#[rustc_error]
-fn main() { //[full_tait]~ ERROR
+fn main() {
+ //~^ ERROR
unsafe { TEST = Some(foo()) }
}
-fn foo() -> Debuggable { //[min_tait]~ ERROR concrete type differs
+fn foo() -> Debuggable {
0u32
}
warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/issue-65679-inst-opaque-ty-from-val-twice.rs:5:32
|
-LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
+LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))]
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/issue-65679-inst-opaque-ty-from-val-twice.rs:5:55
- |
-LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
- | ^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
error: fatal error triggered by #[rustc_error]
- --> $DIR/issue-65679-inst-opaque-ty-from-val-twice.rs:19:1
+ --> $DIR/issue-65679-inst-opaque-ty-from-val-twice.rs:18:1
|
LL | fn main() {
| ^^^^^^^^^
-error: aborting due to previous error; 2 warnings emitted
+error: aborting due to previous error; 1 warning emitted
// revisions: min_tait full_tait
#![feature(min_type_alias_impl_trait, rustc_attrs)]
-#![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
+#![cfg_attr(full_tait, feature(type_alias_impl_trait))]
//[full_tait]~^ WARN incomplete
-//[full_tait]~| WARN incomplete
type T = impl Sized;
// The concrete type referred by impl-trait-type-alias(`T`) is guaranteed
fn take(_: fn() -> T) {}
#[rustc_error]
-fn main() { //[full_tait]~ ERROR fatal error triggered by #[rustc_error]
+fn main() {
+ //[full_tait]~^ ERROR fatal error triggered by #[rustc_error]
take(|| {});
//[min_tait]~^ ERROR not permitted here
take(|| {});
+++ /dev/null
-#![feature(min_type_alias_impl_trait)]
-#![feature(impl_trait_in_bindings)]
-#![allow(incomplete_features)]
-
-type OpaqueOutputImpl<'a> = impl Output<'a> + 'a;
-//~^ ERROR: hidden type for `impl Trait` captures lifetime that does not appear in bounds
-//~| ERROR: the type `&'<empty> str` does not fulfill the required lifetime
-//~| ERROR: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
-
-trait Output<'a> {}
-
-impl<'a> Output<'a> for &'a str {}
-
-fn cool_fn<'a>(arg: &'a str) -> OpaqueOutputImpl<'a> {
- //~^ ERROR: concrete type differs from previous defining opaque type use
- let out: OpaqueOutputImpl<'a> = arg;
- arg
-}
-
-fn main() {
- let s = String::from("wassup");
- cool_fn(&s);
-}
+++ /dev/null
-error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
- --> $DIR/issue-85113.rs:5:29
- |
-LL | type OpaqueOutputImpl<'a> = impl Output<'a> + 'a;
- | ^^^^^^^^^^^^^^^^^^^^
- |
-note: hidden type `&'<empty> str` captures lifetime smaller than the function body
- --> $DIR/issue-85113.rs:5:29
- |
-LL | type OpaqueOutputImpl<'a> = impl Output<'a> + 'a;
- | ^^^^^^^^^^^^^^^^^^^^
-
-error: concrete type differs from previous defining opaque type use
- --> $DIR/issue-85113.rs:14:1
- |
-LL | fn cool_fn<'a>(arg: &'a str) -> OpaqueOutputImpl<'a> {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&'<empty> str`, got `&'a str`
- |
-note: previous use here
- --> $DIR/issue-85113.rs:14:1
- |
-LL | fn cool_fn<'a>(arg: &'a str) -> OpaqueOutputImpl<'a> {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0477]: the type `&'<empty> str` does not fulfill the required lifetime
- --> $DIR/issue-85113.rs:5:29
- |
-LL | type OpaqueOutputImpl<'a> = impl Output<'a> + 'a;
- | ^^^^^^^^^^^^^^^^^^^^
- |
-note: type must outlive the lifetime `'a` as defined on the item at 5:23
- --> $DIR/issue-85113.rs:5:23
- |
-LL | type OpaqueOutputImpl<'a> = impl Output<'a> + 'a;
- | ^^
-
-error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
- --> $DIR/issue-85113.rs:5:29
- |
-LL | type OpaqueOutputImpl<'a> = impl Output<'a> + 'a;
- | ^^^^^^^^^^^^^^^^^^^^
- |
- = note: first, the lifetime cannot outlive the empty lifetime...
-note: ...but the lifetime must also be valid for the lifetime `'a` as defined on the item at 5:23...
- --> $DIR/issue-85113.rs:5:23
- |
-LL | type OpaqueOutputImpl<'a> = impl Output<'a> + 'a;
- | ^^
-note: ...so that the types are compatible
- --> $DIR/issue-85113.rs:5:29
- |
-LL | type OpaqueOutputImpl<'a> = impl Output<'a> + 'a;
- | ^^^^^^^^^^^^^^^^^^^^
- = note: expected `Output<'a>`
- found `Output<'_>`
-
-error: aborting due to 4 previous errors
-
-Some errors have detailed explanations: E0477, E0495, E0700.
-For more information about an error, try `rustc --explain E0477`.
warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/no_inferrable_concrete_type.rs:6:32
|
-LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
+LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))]
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/no_inferrable_concrete_type.rs:6:55
- |
-LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
- | ^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
error: could not find defining uses
- --> $DIR/no_inferrable_concrete_type.rs:10:12
+ --> $DIR/no_inferrable_concrete_type.rs:9:12
|
LL | type Foo = impl Copy;
| ^^^^^^^^^
-error: aborting due to previous error; 2 warnings emitted
+error: aborting due to previous error; 1 warning emitted
-error[E0658]: type alias impl trait is not permitted here
- --> $DIR/no_inferrable_concrete_type.rs:16:12
- |
-LL | let _: Foo = std::mem::transmute(0u8);
- | ^^^
- |
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
- = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
-
error: could not find defining uses
- --> $DIR/no_inferrable_concrete_type.rs:10:12
+ --> $DIR/no_inferrable_concrete_type.rs:9:12
|
LL | type Foo = impl Copy;
| ^^^^^^^^^
-error: aborting due to 2 previous errors
+error: aborting due to previous error
-For more information about this error, try `rustc --explain E0658`.
// revisions: min_tait full_tait
#![feature(min_type_alias_impl_trait)]
-#![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
+#![cfg_attr(full_tait, feature(type_alias_impl_trait))]
//[full_tait]~^ WARN incomplete
-//[full_tait]~| WARN incomplete
type Foo = impl Copy; //~ could not find defining uses
// make compiler happy about using 'Foo'
-fn bar(x: Foo) -> Foo { x }
+fn bar(x: Foo) -> Foo {
+ x
+}
fn main() {
- let _: Foo = std::mem::transmute(0u8); //[min_tait]~ ERROR not permitted here
+ let _: Foo = std::mem::transmute(0u8);
}
warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/structural-match-no-leak.rs:4:32
|
-LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
+LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))]
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/structural-match-no-leak.rs:4:55
- |
-LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
- | ^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
error: `impl Send` cannot be used in patterns
- --> $DIR/structural-match-no-leak.rs:19:9
+ --> $DIR/structural-match-no-leak.rs:18:9
|
LL | LEAK_FREE => (),
| ^^^^^^^^^
-error: aborting due to previous error; 2 warnings emitted
+error: aborting due to previous error; 1 warning emitted
-error[E0658]: type alias impl trait is not permitted here
- --> $DIR/structural-match-no-leak.rs:15:24
+error: `impl Send` cannot be used in patterns
+ --> $DIR/structural-match-no-leak.rs:18:9
|
-LL | const LEAK_FREE: Bar = leak_free();
- | ^^^^^^^^^^^
- |
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
- = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
+LL | LEAK_FREE => (),
+ | ^^^^^^^^^
error: aborting due to previous error
-For more information about this error, try `rustc --explain E0658`.
#![feature(const_impl_trait)]
// revisions: min_tait full_tait
#![feature(min_type_alias_impl_trait)]
-#![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
+#![cfg_attr(full_tait, feature(type_alias_impl_trait))]
//[full_tait]~^ WARN incomplete
-//[full_tait]~| WARN incomplete
type Bar = impl Send;
const fn leak_free() -> Bar {
7i32
}
-const LEAK_FREE: Bar = leak_free(); //[min_tait]~ ERROR not permitted here
+const LEAK_FREE: Bar = leak_free();
fn leak_free_test() {
match todo!() {
LEAK_FREE => (),
- //[full_tait]~^ `impl Send` cannot be used in patterns
+ //~^ `impl Send` cannot be used in patterns
_ => (),
}
}
warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes
--> $DIR/structural-match.rs:4:32
|
-LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
+LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))]
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/structural-match.rs:4:55
- |
-LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
- | ^^^^^^^^^^^^^^^^^^^^^^
- |
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
-
error: `impl Send` cannot be used in patterns
- --> $DIR/structural-match.rs:20:9
+ --> $DIR/structural-match.rs:19:9
|
LL | VALUE => (),
| ^^^^^
-error: aborting due to previous error; 2 warnings emitted
+error: aborting due to previous error; 1 warning emitted
-error[E0658]: type alias impl trait is not permitted here
- --> $DIR/structural-match.rs:16:20
+error: `impl Send` cannot be used in patterns
+ --> $DIR/structural-match.rs:19:9
|
-LL | const VALUE: Foo = value();
- | ^^^^^^^
- |
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
- = help: add `#![feature(impl_trait_in_bindings)]` to the crate attributes to enable
+LL | VALUE => (),
+ | ^^^^^
error: aborting due to previous error
-For more information about this error, try `rustc --explain E0658`.
#![feature(const_impl_trait)]
// revisions: min_tait full_tait
#![feature(min_type_alias_impl_trait)]
-#![cfg_attr(full_tait, feature(type_alias_impl_trait, impl_trait_in_bindings))]
+#![cfg_attr(full_tait, feature(type_alias_impl_trait))]
//[full_tait]~^ WARN incomplete
-//[full_tait]~| WARN incomplete
type Foo = impl Send;
const fn value() -> Foo {
A
}
-const VALUE: Foo = value(); //[min_tait]~ ERROR not permitted here
+const VALUE: Foo = value();
fn test() {
match todo!() {
VALUE => (),
- //[full_tait]~^ `impl Send` cannot be used in patterns
+ //~^ `impl Send` cannot be used in patterns
_ => (),
}
}
warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/type-alias-impl-trait-const.rs:5:32
+ --> $DIR/type-alias-impl-trait-const.rs:3:32
|
LL | #![cfg_attr(full_tait, feature(type_alias_impl_trait))]
| ^^^^^^^^^^^^^^^^^^^^^
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/type-alias-impl-trait-const.rs:11:12
+error[E0308]: mismatched types
+ --> $DIR/type-alias-impl-trait-const.rs:13:19
|
-LL | #![feature(impl_trait_in_bindings)]
- | ^^^^^^^^^^^^^^^^^^^^^^
+LL | pub type Foo = impl Debug;
+ | ---------- the expected opaque type
+...
+LL | const _FOO: Foo = 5;
+ | ^ expected opaque type, found integer
|
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
+ = note: expected opaque type `impl Debug`
+ found type `{integer}`
-warning: 2 warnings emitted
+error: could not find defining uses
+ --> $DIR/type-alias-impl-trait-const.rs:10:16
+ |
+LL | pub type Foo = impl Debug;
+ | ^^^^^^^^^^
+
+error: aborting due to 2 previous errors; 1 warning emitted
+For more information about this error, try `rustc --explain E0308`.
-warning: the feature `impl_trait_in_bindings` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/type-alias-impl-trait-const.rs:11:12
+error[E0308]: mismatched types
+ --> $DIR/type-alias-impl-trait-const.rs:13:19
|
-LL | #![feature(impl_trait_in_bindings)]
- | ^^^^^^^^^^^^^^^^^^^^^^
+LL | pub type Foo = impl Debug;
+ | ---------- the expected opaque type
+...
+LL | const _FOO: Foo = 5;
+ | ^ expected opaque type, found integer
|
- = note: `#[warn(incomplete_features)]` on by default
- = note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
+ = note: expected opaque type `impl Debug`
+ found type `{integer}`
-warning: 1 warning emitted
+error: could not find defining uses
+ --> $DIR/type-alias-impl-trait-const.rs:10:16
+ |
+LL | pub type Foo = impl Debug;
+ | ^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+For more information about this error, try `rustc --explain E0308`.
-// check-pass
-
// revisions: min_tait full_tait
#![feature(min_type_alias_impl_trait)]
#![cfg_attr(full_tait, feature(type_alias_impl_trait))]
//[full_tait]~^ WARN incomplete
-// Currently, the `type_alias_impl_trait` feature implicitly
-// depends on `impl_trait_in_bindings` in order to work properly.
-// Specifically, this line requires `impl_trait_in_bindings` to be enabled:
-// https://github.com/rust-lang/rust/blob/481068a707679257e2a738b40987246e0420e787/compiler/rustc_typeck/check/mod.rs#L856
-#![feature(impl_trait_in_bindings)]
-//~^ WARN the feature `impl_trait_in_bindings` is incomplete
// Ensures that `const` items can constrain an opaque `impl Trait`.
use std::fmt::Debug;
pub type Foo = impl Debug;
+//~^ ERROR could not find defining uses
const _FOO: Foo = 5;
+//~^ ERROR mismatched types [E0308]
-fn main() {
-}
+fn main() {}
--> $DIR/type-check-defaults.rs:11:17
|
LL | struct Bounds<T:Copy=String>(T);
- | ----------------^^^^------------
- | | |
- | | the trait `Copy` is not implemented for `String`
- | required by `Bounds`
+ | ^^^^ the trait `Copy` is not implemented for `String`
+ |
+note: required by `Bounds`
+ --> $DIR/type-check-defaults.rs:11:1
+ |
+LL | struct Bounds<T:Copy=String>(T);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the trait bound `String: Copy` is not satisfied
--> $DIR/type-check-defaults.rs:14:42
|
LL | struct WhereClause<T=String>(T) where T: Copy;
- | -----------------------------------------^^^^-
- | | |
- | | the trait `Copy` is not implemented for `String`
- | required by `WhereClause`
+ | ^^^^ the trait `Copy` is not implemented for `String`
+ |
+note: required by `WhereClause`
+ --> $DIR/type-check-defaults.rs:14:1
+ |
+LL | struct WhereClause<T=String>(T) where T: Copy;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the trait bound `String: Copy` is not satisfied
--> $DIR/type-check-defaults.rs:17:20
|
LL | trait TraitBound<T:Copy=String> {}
- | -------------------^^^^--------
- | | |
- | | the trait `Copy` is not implemented for `String`
- | required by `TraitBound`
+ | ^^^^ the trait `Copy` is not implemented for `String`
+ |
+note: required by `TraitBound`
+ --> $DIR/type-check-defaults.rs:17:1
+ |
+LL | trait TraitBound<T:Copy=String> {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: the trait bound `T: Copy` is not satisfied
--> $DIR/type-check-defaults.rs:21:25
--> $DIR/type-check-defaults.rs:24:66
|
LL | trait ProjectionPred<T:Iterator = IntoIter<i32>> where T::Item : Add<u8> {}
- | -----------------------------------------------------------------^^^^^^^
- | | |
- | | no implementation for `i32 + u8`
- | required by `ProjectionPred`
+ | ^^^^^^^ no implementation for `i32 + u8`
|
= help: the trait `Add<u8>` is not implemented for `i32`
+note: required by `ProjectionPred`
+ --> $DIR/type-check-defaults.rs:24:1
+ |
+LL | trait ProjectionPred<T:Iterator = IntoIter<i32>> where T::Item : Add<u8> {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 7 previous errors
error[E0277]: the trait bound `Self: Tr<U>` is not satisfied
--> $DIR/type-params-in-different-spaces-2.rs:10:9
|
-LL | fn op(_: T) -> Self;
- | -------------------- required by `Tr::op`
-...
LL | Tr::op(u)
| ^^^^^^ the trait `Tr<U>` is not implemented for `Self`
|
+note: required by `Tr::op`
+ --> $DIR/type-params-in-different-spaces-2.rs:5:5
+ |
+LL | fn op(_: T) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^
help: consider further restricting `Self`
|
LL | fn test<U>(u: U) -> Self where Self: Tr<U> {
error[E0277]: the trait bound `Self: Tr<U>` is not satisfied
--> $DIR/type-params-in-different-spaces-2.rs:16:9
|
-LL | fn op(_: T) -> Self;
- | -------------------- required by `Tr::op`
-...
LL | Tr::op(u)
| ^^^^^^ the trait `Tr<U>` is not implemented for `Self`
|
+note: required by `Tr::op`
+ --> $DIR/type-params-in-different-spaces-2.rs:5:5
+ |
+LL | fn op(_: T) -> Self;
+ | ^^^^^^^^^^^^^^^^^^^^
help: consider further restricting `Self`
|
LL | fn test<U>(u: U) -> Self where Self: Tr<U> {
| ^^^^^^^^^^^^^^^^^^^^^^ no implementation for `i32 + u32`
|
= help: the trait `Add<u32>` is not implemented for `i32`
- = note: required by `add`
+note: required by `add`
+ --> $SRC_DIR/core/src/ops/arith.rs:LL:COL
+ |
+LL | fn add(self, rhs: Rhs) -> Self::Output;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0308]: mismatched types
--> $DIR/ufcs-qpath-self-mismatch.rs:6:28
error[E0277]: the trait bound `[(); 0]: Foo` is not satisfied
--> $DIR/unevaluated_fixed_size_array_len.rs:12:5
|
-LL | fn foo();
- | --------- required by `Foo::foo`
-...
LL | <[(); 0] as Foo>::foo()
| ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `[(); 0]`
|
= help: the following implementations were found:
<[(); 1] as Foo>
+note: required by `Foo::foo`
+ --> $DIR/unevaluated_fixed_size_array_len.rs:4:5
+ |
+LL | fn foo();
+ | ^^^^^^^^^
error: aborting due to previous error
error[E0277]: the trait bound `PartialEqNotEq: Eq` is not satisfied
--> $DIR/union-derive-eq.rs:16:5
|
+LL | #[derive(Eq)]
+ | -- in this derive macro expansion
+LL | union U2 {
LL | a: PartialEqNotEq,
| ^^^^^^^^^^^^^^^^^ the trait `Eq` is not implemented for `PartialEqNotEq`
|
error[E0277]: the trait bound `PartialEqNotEq: Eq` is not satisfied
--> $DIR/union-derive-eq.rs:16:5
|
+LL | #[derive(Eq)]
+ | -- in this derive macro expansion
+LL | union U2 {
LL | a: PartialEqNotEq,
| ^^^^^^^^^^^^^^^^^ the trait `Eq` is not implemented for `PartialEqNotEq`
|
error[E0277]: the trait bound `Rc<u32>: Copy` is not satisfied
--> $DIR/union-generic.rs:11:13
|
-LL | union U<T: Copy> {
- | ---------------- required by `U`
-...
LL | let u = U { a: Rc::new(0u32) };
| ^ the trait `Copy` is not implemented for `Rc<u32>`
+ |
+note: required by `U`
+ --> $DIR/union-generic.rs:6:1
+ |
+LL | union U<T: Copy> {
+ | ^^^^^^^^^^^^^^^^
error[E0277]: the trait bound `Rc<u32>: Copy` is not satisfied
--> $DIR/union-generic.rs:13:13
|
-LL | union U<T: Copy> {
- | ---------------- required by `U`
-...
LL | let u = U::<Rc<u32>> { a: Default::default() };
| ^^^^^^^^^^^^ the trait `Copy` is not implemented for `Rc<u32>`
+ |
+note: required by `U`
+ --> $DIR/union-generic.rs:6:1
+ |
+LL | union U<T: Copy> {
+ | ^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
error[E0277]: the trait bound `Rc<u32>: Copy` is not satisfied
--> $DIR/union-generic.rs:11:13
|
-LL | union U<T: Copy> {
- | ---------------- required by `U`
-...
LL | let u = U { a: Rc::new(0u32) };
| ^ the trait `Copy` is not implemented for `Rc<u32>`
+ |
+note: required by `U`
+ --> $DIR/union-generic.rs:6:1
+ |
+LL | union U<T: Copy> {
+ | ^^^^^^^^^^^^^^^^
error[E0277]: the trait bound `Rc<u32>: Copy` is not satisfied
--> $DIR/union-generic.rs:13:13
|
-LL | union U<T: Copy> {
- | ---------------- required by `U`
-...
LL | let u = U::<Rc<u32>> { a: Default::default() };
| ^^^^^^^^^^^^ the trait `Copy` is not implemented for `Rc<u32>`
+ |
+note: required by `U`
+ --> $DIR/union-generic.rs:6:1
+ |
+LL | union U<T: Copy> {
+ | ^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
error[E0277]: the trait bound `(): Foo` is not satisfied
- --> $DIR/wf-foreign-fn-decl-ret.rs:11:12
+ --> $DIR/wf-foreign-fn-decl-ret.rs:11:25
|
+LL | pub trait Foo {
+ | ------------- required by this bound in `Foo`
+...
LL | pub fn lint_me() -> <() as Foo>::Assoc;
- | ^^^^^^^ the trait `Foo` is not implemented for `()`
+ | ^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()`
error[E0277]: the trait bound `u32: Unsatisfied` is not satisfied
--> $DIR/wf-foreign-fn-decl-ret.rs:14:32
error[E0277]: the trait bound `T: Copy` is not satisfied
- --> $DIR/wf-in-fn-arg.rs:10:14
+ --> $DIR/wf-in-fn-arg.rs:10:15
|
LL | struct MustBeCopy<T:Copy> {
| ---- required by this bound in `MustBeCopy`
...
LL | fn bar<T>(_: &MustBeCopy<T>)
- | ^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
+ | ^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T`
|
help: consider restricting type parameter `T`
|
impl Trait for Ref {} //~ ERROR: implicit elided lifetime not allowed here
extern "C" {
- pub fn repro(_: Wrapper<Ref>); //~ ERROR: mismatched types
+ pub fn repro(_: Wrapper<Ref>); //~ ERROR: incompatible lifetime on type
}
|
LL | impl Trait for Ref {}
| ^^^- help: indicate the anonymous lifetime: `<'_>`
+ |
+ = note: assuming a `'static` lifetime...
-error[E0308]: mismatched types
+error: incompatible lifetime on type
--> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:16:21
|
LL | pub fn repro(_: Wrapper<Ref>);
- | ^^^^^^^^^^^^ lifetime mismatch
+ | ^^^^^^^^^^^^
+ |
+note: because this has an unmet lifetime requirement
+ --> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:8:23
|
- = note: expected trait `Trait`
- found trait `Trait`
+LL | pub struct Wrapper<T: Trait>(T);
+ | ^^^^^ introduces a `'static` lifetime requirement
note: the anonymous lifetime #1 defined on the method body at 16:5...
--> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:16:5
|
LL | pub fn repro(_: Wrapper<Ref>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- = note: ...does not necessarily outlive the static lifetime
+note: ...does not necessarily outlive the static lifetime introduced by the compatible `impl`
+ --> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:13:1
+ |
+LL | impl Trait for Ref {}
+ | ^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
-For more information about this error, try `rustc --explain E0308`.
error[E0277]: the trait bound `Self: Eq` is not satisfied
- --> $DIR/wf-trait-default-fn-arg.rs:11:22
+ --> $DIR/wf-trait-default-fn-arg.rs:11:23
|
LL | struct Bar<T:Eq+?Sized> { value: Box<T> }
| -- required by this bound in `Bar`
...
LL | fn bar(&self, x: &Bar<Self>) {
- | ^^^^^^^^^^ the trait `Eq` is not implemented for `Self`
+ | ^^^^^^^^^ the trait `Eq` is not implemented for `Self`
|
help: consider further restricting `Self`
|
error[E0277]: the trait bound `Self: Eq` is not satisfied
- --> $DIR/wf-trait-fn-arg.rs:10:22
+ --> $DIR/wf-trait-fn-arg.rs:10:23
|
LL | struct Bar<T:Eq+?Sized> { value: Box<T> }
| -- required by this bound in `Bar`
...
LL | fn bar(&self, x: &Bar<Self>);
- | ^^^^^^^^^^ the trait `Eq` is not implemented for `Self`
+ | ^^^^^^^^^ the trait `Eq` is not implemented for `Self`
|
help: consider further restricting `Self`
|
|
LL | let _ = xc_private_method_lib::Struct::static_meth_struct();
| ^^^^^^^^^^^^^^^^^^ private associated function
+ |
+ ::: $DIR/auxiliary/xc-private-method-lib.rs:8:5
+ |
+LL | fn static_meth_struct() -> Struct {
+ | --------------------------------- private associated function defined here
error[E0624]: associated function `static_meth_enum` is private
--> $DIR/xc-private-method.rs:9:42
|
LL | let _ = xc_private_method_lib::Enum::static_meth_enum();
| ^^^^^^^^^^^^^^^^ private associated function
+ |
+ ::: $DIR/auxiliary/xc-private-method-lib.rs:23:5
+ |
+LL | fn static_meth_enum() -> Enum {
+ | ----------------------------- private associated function defined here
error: aborting due to 2 previous errors
|
LL | let _ = xc_private_method_lib::Struct{ x: 10 }.meth_struct();
| ^^^^^^^^^^^ private associated function
+ |
+ ::: $DIR/auxiliary/xc-private-method-lib.rs:12:5
+ |
+LL | fn meth_struct(&self) -> isize {
+ | ------------------------------ private associated function defined here
error[E0624]: associated function `meth_enum` is private
--> $DIR/xc-private-method2.rs:9:55
|
LL | let _ = xc_private_method_lib::Enum::Variant1(20).meth_enum();
| ^^^^^^^^^ private associated function
+ |
+ ::: $DIR/auxiliary/xc-private-method-lib.rs:27:5
+ |
+LL | fn meth_enum(&self) -> isize {
+ | ---------------------------- private associated function defined here
error: aborting due to 2 previous errors
-Subproject commit 27277d966b3cfa454d6dea7f724cb961c036251c
+Subproject commit 4e143fd131e0c16cefd008456e974236ca54e62e
[`same_item_push`]: https://rust-lang.github.io/rust-clippy/master/index.html#same_item_push
[`search_is_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#search_is_some
[`self_assignment`]: https://rust-lang.github.io/rust-clippy/master/index.html#self_assignment
+[`self_named_constructor`]: https://rust-lang.github.io/rust-clippy/master/index.html#self_named_constructor
[`semicolon_if_nothing_returned`]: https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_if_nothing_returned
[`serde_api_misuse`]: https://rust-lang.github.io/rust-clippy/master/index.html#serde_api_misuse
[`shadow_reuse`]: https://rust-lang.github.io/rust-clippy/master/index.html#shadow_reuse
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::snippet_opt;
use clippy_utils::ty::implements_trait;
-use clippy_utils::{eq_expr_value, get_trait_def_id, trait_ref_of_method};
-use clippy_utils::{higher, paths, sugg};
+use clippy_utils::{binop_traits, sugg};
+use clippy_utils::{eq_expr_value, trait_ref_of_method};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir as hir;
let lint = |assignee: &hir::Expr<'_>, rhs: &hir::Expr<'_>| {
let ty = cx.typeck_results().expr_ty(assignee);
let rty = cx.typeck_results().expr_ty(rhs);
- macro_rules! ops {
- ($op:expr,
- $cx:expr,
- $ty:expr,
- $rty:expr,
- $($trait_name:ident),+) => {
- match $op {
- $(hir::BinOpKind::$trait_name => {
- let [krate, module] = paths::OPS_MODULE;
- let path: [&str; 3] = [krate, module, concat!(stringify!($trait_name), "Assign")];
- let trait_id = if let Some(trait_id) = get_trait_def_id($cx, &path) {
- trait_id
- } else {
- return; // useless if the trait doesn't exist
- };
- // check that we are not inside an `impl AssignOp` of this exact operation
- let parent_fn = cx.tcx.hir().get_parent_item(e.hir_id);
- if_chain! {
- if let Some(trait_ref) = trait_ref_of_method(cx, parent_fn);
- if trait_ref.path.res.def_id() == trait_id;
- then { return; }
+ if_chain! {
+ if let Some((_, lang_item)) = binop_traits(op.node);
+ if let Ok(trait_id) = cx.tcx.lang_items().require(lang_item);
+ let parent_fn = cx.tcx.hir().get_parent_item(e.hir_id);
+ if trait_ref_of_method(cx, parent_fn)
+ .map_or(true, |t| t.path.res.def_id() != trait_id);
+ if implements_trait(cx, ty, trait_id, &[rty.into()]);
+ then {
+ span_lint_and_then(
+ cx,
+ ASSIGN_OP_PATTERN,
+ expr.span,
+ "manual implementation of an assign operation",
+ |diag| {
+ if let (Some(snip_a), Some(snip_r)) =
+ (snippet_opt(cx, assignee.span), snippet_opt(cx, rhs.span))
+ {
+ diag.span_suggestion(
+ expr.span,
+ "replace it with",
+ format!("{} {}= {}", snip_a, op.node.as_str(), snip_r),
+ Applicability::MachineApplicable,
+ );
}
- implements_trait($cx, $ty, trait_id, &[$rty])
- },)*
- _ => false,
- }
+ },
+ );
}
}
- if ops!(
- op.node,
- cx,
- ty,
- rty.into(),
- Add,
- Sub,
- Mul,
- Div,
- Rem,
- And,
- Or,
- BitAnd,
- BitOr,
- BitXor,
- Shr,
- Shl
- ) {
- span_lint_and_then(
- cx,
- ASSIGN_OP_PATTERN,
- expr.span,
- "manual implementation of an assign operation",
- |diag| {
- if let (Some(snip_a), Some(snip_r)) =
- (snippet_opt(cx, assignee.span), snippet_opt(cx, rhs.span))
- {
- diag.span_suggestion(
- expr.span,
- "replace it with",
- format!("{} {}= {}", snip_a, op.node.as_str(), snip_r),
- Applicability::MachineApplicable,
- );
- }
- },
- );
- }
};
let mut visitor = ExprVisitor {
if let (Some(snip_a), Some(snip_r)) = (snippet_opt(cx, assignee.span), snippet_opt(cx, rhs_other.span)) {
let a = &sugg::Sugg::hir(cx, assignee, "..");
let r = &sugg::Sugg::hir(cx, rhs, "..");
- let long = format!("{} = {}", snip_a, sugg::make_binop(higher::binop(op.node), a, r));
+ let long = format!("{} = {}", snip_a, sugg::make_binop(op.node.into(), a, r));
diag.span_suggestion(
expr.span,
&format!(
if macro_with_not_op(&left.kind) || macro_with_not_op(&right.kind) {
return;
}
- if is_useless_with_eq_exprs(higher::binop(op.node)) && eq_expr_value(cx, left, right) {
+ if is_useless_with_eq_exprs(op.node.into()) && eq_expr_value(cx, left, right) {
span_lint(
cx,
EQ_OP,
mod repeat_once;
mod returns;
mod self_assignment;
+mod self_named_constructor;
mod semicolon_if_nothing_returned;
mod serde_api;
mod shadow;
returns::LET_AND_RETURN,
returns::NEEDLESS_RETURN,
self_assignment::SELF_ASSIGNMENT,
+ self_named_constructor::SELF_NAMED_CONSTRUCTOR,
semicolon_if_nothing_returned::SEMICOLON_IF_NOTHING_RETURNED,
serde_api::SERDE_API_MISUSE,
shadow::SHADOW_REUSE,
LintId::of(returns::LET_AND_RETURN),
LintId::of(returns::NEEDLESS_RETURN),
LintId::of(self_assignment::SELF_ASSIGNMENT),
+ LintId::of(self_named_constructor::SELF_NAMED_CONSTRUCTOR),
LintId::of(serde_api::SERDE_API_MISUSE),
LintId::of(single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS),
LintId::of(size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT),
LintId::of(redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES),
LintId::of(returns::LET_AND_RETURN),
LintId::of(returns::NEEDLESS_RETURN),
+ LintId::of(self_named_constructor::SELF_NAMED_CONSTRUCTOR),
LintId::of(single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS),
LintId::of(tabs_in_doc_comments::TABS_IN_DOC_COMMENTS),
LintId::of(to_digit_is_some::TO_DIGIT_IS_SOME),
let scripts = conf.allowed_scripts.clone();
store.register_early_pass(move || box disallowed_script_idents::DisallowedScriptIdents::new(&scripts));
store.register_late_pass(|| box strlen_on_c_strings::StrlenOnCStrings);
+ store.register_late_pass(move || box self_named_constructor::SelfNamedConstructor);
}
#[rustfmt::skip]
expr: &Expr<'_>,
els: Option<&Expr<'_>>,
) {
- if is_wild(&arms[1].pat) {
+ if is_wild(arms[1].pat) {
report_single_match_single_pattern(cx, ex, arms, expr, els);
}
}
if let Some((b1_arm, b0_arms)) = arms.split_last();
if let Some(b0) = find_bool_lit(&b0_arms[0].body.kind, desugared);
if let Some(b1) = find_bool_lit(&b1_arm.body.kind, desugared);
- if is_wild(&b1_arm.pat);
+ if is_wild(b1_arm.pat);
if b0 != b1;
let if_guard = &b0_arms[0].guard;
if if_guard.is_none() || b0_arms.len() == 1;
--- /dev/null
+use clippy_utils::diagnostics::span_lint;
+use clippy_utils::return_ty;
+use clippy_utils::ty::{contains_adt_constructor, contains_ty};
+use rustc_hir::{Impl, ImplItem, ImplItemKind, ItemKind, Node};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_session::{declare_lint_pass, declare_tool_lint};
+
+declare_clippy_lint! {
+ /// **What it does:** Warns when constructors have the same name as their types.
+ ///
+ /// **Why is this bad?** Repeating the name of the type is redundant.
+ ///
+ /// **Known problems:** None.
+ ///
+ /// **Example:**
+ ///
+ /// ```rust,ignore
+ /// struct Foo {}
+ ///
+ /// impl Foo {
+ /// pub fn foo() -> Foo {
+ /// Foo {}
+ /// }
+ /// }
+ /// ```
+ /// Use instead:
+ /// ```rust,ignore
+ /// struct Foo {}
+ ///
+ /// impl Foo {
+ /// pub fn new() -> Foo {
+ /// Foo {}
+ /// }
+ /// }
+ /// ```
+ pub SELF_NAMED_CONSTRUCTOR,
+ style,
+ "method should not have the same name as the type it is implemented for"
+}
+
+declare_lint_pass!(SelfNamedConstructor => [SELF_NAMED_CONSTRUCTOR]);
+
+impl<'tcx> LateLintPass<'tcx> for SelfNamedConstructor {
+ fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<'_>) {
+ match impl_item.kind {
+ ImplItemKind::Fn(ref sig, _) => {
+ if sig.decl.implicit_self.has_implicit_self() {
+ return;
+ }
+ },
+ _ => return,
+ }
+
+ let parent = cx.tcx.hir().get_parent_item(impl_item.hir_id());
+ let item = cx.tcx.hir().expect_item(parent);
+ let self_ty = cx.tcx.type_of(item.def_id);
+ let ret_ty = return_ty(cx, impl_item.hir_id());
+
+ // Do not check trait impls
+ if matches!(item.kind, ItemKind::Impl(Impl { of_trait: Some(_), .. })) {
+ return;
+ }
+
+ // Ensure method is constructor-like
+ if let Some(self_adt) = self_ty.ty_adt_def() {
+ if !contains_adt_constructor(ret_ty, self_adt) {
+ return;
+ }
+ } else if !contains_ty(ret_ty, self_ty) {
+ return;
+ }
+
+ if_chain! {
+ if let Some(self_def) = self_ty.ty_adt_def();
+ if let Some(self_local_did) = self_def.did.as_local();
+ let self_id = cx.tcx.hir().local_def_id_to_hir_id(self_local_did);
+ if let Some(Node::Item(x)) = cx.tcx.hir().find(self_id);
+ let type_name = x.ident.name.as_str().to_lowercase();
+ if impl_item.ident.name.as_str() == type_name || impl_item.ident.name.as_str().replace("_", "") == type_name;
+
+ then {
+ span_lint(
+ cx,
+ SELF_NAMED_CONSTRUCTOR,
+ impl_item.span,
+ &format!("constructor `{}` has the same name as the type", impl_item.ident.name),
+ );
+ }
+ }
+ }
+}
use clippy_utils::diagnostics::span_lint;
-use clippy_utils::{get_trait_def_id, paths, trait_ref_of_method};
+use clippy_utils::{binop_traits, trait_ref_of_method, BINOP_TRAITS, OP_ASSIGN_TRAITS};
use if_chain::if_chain;
use rustc_hir as hir;
use rustc_hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
impl<'tcx> LateLintPass<'tcx> for SuspiciousImpl {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
- if let hir::ExprKind::Binary(binop, _, _) | hir::ExprKind::AssignOp(binop, ..) = expr.kind {
- match binop.node {
- hir::BinOpKind::Eq
- | hir::BinOpKind::Lt
- | hir::BinOpKind::Le
- | hir::BinOpKind::Ne
- | hir::BinOpKind::Ge
- | hir::BinOpKind::Gt => return,
- _ => {},
- }
+ if_chain! {
+ if let hir::ExprKind::Binary(binop, _, _) | hir::ExprKind::AssignOp(binop, ..) = expr.kind;
+ if let Some((binop_trait_lang, op_assign_trait_lang)) = binop_traits(binop.node);
+ if let Ok(binop_trait_id) = cx.tcx.lang_items().require(binop_trait_lang);
+ if let Ok(op_assign_trait_id) = cx.tcx.lang_items().require(op_assign_trait_lang);
// Check for more than one binary operation in the implemented function
// Linting when multiple operations are involved can result in false positives
let parent_fn = cx.tcx.hir().get_parent_item(expr.hir_id);
- if_chain! {
- if let hir::Node::ImplItem(impl_item) = cx.tcx.hir().get(parent_fn);
- if let hir::ImplItemKind::Fn(_, body_id) = impl_item.kind;
- then {
- let body = cx.tcx.hir().body(body_id);
- let mut visitor = BinaryExprVisitor { nb_binops: 0 };
- walk_expr(&mut visitor, &body.value);
- if visitor.nb_binops > 1 {
- return;
- }
- }
- }
-
- if let Some(impl_trait) = check_binop(
- cx,
- expr,
- binop.node,
- &[
- "Add", "Sub", "Mul", "Div", "Rem", "BitAnd", "BitOr", "BitXor", "Shl", "Shr",
- ],
- &[
- hir::BinOpKind::Add,
- hir::BinOpKind::Sub,
- hir::BinOpKind::Mul,
- hir::BinOpKind::Div,
- hir::BinOpKind::Rem,
- hir::BinOpKind::BitAnd,
- hir::BinOpKind::BitOr,
- hir::BinOpKind::BitXor,
- hir::BinOpKind::Shl,
- hir::BinOpKind::Shr,
- ],
- ) {
- span_lint(
- cx,
- SUSPICIOUS_ARITHMETIC_IMPL,
- binop.span,
- &format!("suspicious use of binary operator in `{}` impl", impl_trait),
- );
- }
-
- if let Some(impl_trait) = check_binop(
- cx,
- expr,
- binop.node,
- &[
- "AddAssign",
- "SubAssign",
- "MulAssign",
- "DivAssign",
- "BitAndAssign",
- "BitOrAssign",
- "BitXorAssign",
- "RemAssign",
- "ShlAssign",
- "ShrAssign",
- ],
- &[
- hir::BinOpKind::Add,
- hir::BinOpKind::Sub,
- hir::BinOpKind::Mul,
- hir::BinOpKind::Div,
- hir::BinOpKind::BitAnd,
- hir::BinOpKind::BitOr,
- hir::BinOpKind::BitXor,
- hir::BinOpKind::Rem,
- hir::BinOpKind::Shl,
- hir::BinOpKind::Shr,
- ],
- ) {
+ if let hir::Node::ImplItem(impl_item) = cx.tcx.hir().get(parent_fn);
+ if let hir::ImplItemKind::Fn(_, body_id) = impl_item.kind;
+ let body = cx.tcx.hir().body(body_id);
+ let parent_fn = cx.tcx.hir().get_parent_item(expr.hir_id);
+ if let Some(trait_ref) = trait_ref_of_method(cx, parent_fn);
+ let trait_id = trait_ref.path.res.def_id();
+ if ![binop_trait_id, op_assign_trait_id].contains(&trait_id);
+ if let Some(&(_, lint)) = [
+ (&BINOP_TRAITS, SUSPICIOUS_ARITHMETIC_IMPL),
+ (&OP_ASSIGN_TRAITS, SUSPICIOUS_OP_ASSIGN_IMPL),
+ ]
+ .iter()
+ .find(|&(ts, _)| ts.iter().any(|&t| Ok(trait_id) == cx.tcx.lang_items().require(t)));
+ if count_binops(&body.value) == 1;
+ then {
span_lint(
cx,
- SUSPICIOUS_OP_ASSIGN_IMPL,
+ lint,
binop.span,
- &format!("suspicious use of binary operator in `{}` impl", impl_trait),
+ &format!("suspicious use of `{}` in `{}` impl", binop.node.as_str(), cx.tcx.item_name(trait_id)),
);
}
}
}
}
-fn check_binop(
- cx: &LateContext<'_>,
- expr: &hir::Expr<'_>,
- binop: hir::BinOpKind,
- traits: &[&'static str],
- expected_ops: &[hir::BinOpKind],
-) -> Option<&'static str> {
- let mut trait_ids = vec![];
- let [krate, module] = paths::OPS_MODULE;
-
- for &t in traits {
- let path = [krate, module, t];
- if let Some(trait_id) = get_trait_def_id(cx, &path) {
- trait_ids.push(trait_id);
- } else {
- return None;
- }
- }
-
- // Get the actually implemented trait
- let parent_fn = cx.tcx.hir().get_parent_item(expr.hir_id);
-
- if_chain! {
- if let Some(trait_ref) = trait_ref_of_method(cx, parent_fn);
- if let Some(idx) = trait_ids.iter().position(|&tid| tid == trait_ref.path.res.def_id());
- if binop != expected_ops[idx];
- then{
- return Some(traits[idx])
- }
- }
-
- None
+fn count_binops(expr: &hir::Expr<'_>) -> u32 {
+ let mut visitor = BinaryExprVisitor::default();
+ visitor.visit_expr(expr);
+ visitor.nb_binops
}
+#[derive(Default)]
struct BinaryExprVisitor {
nb_binops: u32,
}
use if_chain::if_chain;
use rustc_hir::{self as hir, HirId, ItemKind, Node};
use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty::{Adt, Ty};
+use rustc_middle::ty::{Adt, Ty, TypeFoldable};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym;
use rustc_target::abi::LayoutOf as _;
if is_type_diagnostic_item(cx, ty, sym::hashmap_type) || match_type(cx, ty, &paths::BTREEMAP);
if let Adt(_, substs) = ty.kind();
let ty = substs.type_at(1);
+ // Fixes https://github.com/rust-lang/rust-clippy/issues/7447 because of
+ // https://github.com/rust-lang/rust/blob/master/compiler/rustc_middle/src/ty/sty.rs#L968
+ if !ty.has_escaping_bound_vars();
// Do this to prevent `layout_of` crashing, being unable to fully normalize `ty`.
if is_normalizable(cx, cx.param_env, ty);
if let Ok(layout) = cx.layout_of(ty);
use rustc_lint::LateContext;
use rustc_span::{sym, ExpnKind, Span, Symbol};
-/// Converts a hir binary operator to the corresponding `ast` type.
-#[must_use]
-pub fn binop(op: hir::BinOpKind) -> ast::BinOpKind {
- match op {
- hir::BinOpKind::Eq => ast::BinOpKind::Eq,
- hir::BinOpKind::Ge => ast::BinOpKind::Ge,
- hir::BinOpKind::Gt => ast::BinOpKind::Gt,
- hir::BinOpKind::Le => ast::BinOpKind::Le,
- hir::BinOpKind::Lt => ast::BinOpKind::Lt,
- hir::BinOpKind::Ne => ast::BinOpKind::Ne,
- hir::BinOpKind::Or => ast::BinOpKind::Or,
- hir::BinOpKind::Add => ast::BinOpKind::Add,
- hir::BinOpKind::And => ast::BinOpKind::And,
- hir::BinOpKind::BitAnd => ast::BinOpKind::BitAnd,
- hir::BinOpKind::BitOr => ast::BinOpKind::BitOr,
- hir::BinOpKind::BitXor => ast::BinOpKind::BitXor,
- hir::BinOpKind::Div => ast::BinOpKind::Div,
- hir::BinOpKind::Mul => ast::BinOpKind::Mul,
- hir::BinOpKind::Rem => ast::BinOpKind::Rem,
- hir::BinOpKind::Shl => ast::BinOpKind::Shl,
- hir::BinOpKind::Shr => ast::BinOpKind::Shr,
- hir::BinOpKind::Sub => ast::BinOpKind::Sub,
- }
-}
-
/// Represent a range akin to `ast::ExprKind::Range`.
#[derive(Debug, Copy, Clone)]
pub struct Range<'a> {
if is_integer_literal(e, value) {
return true;
}
- let map = cx.tcx.hir();
- let parent_item = map.get_parent_item(e.hir_id);
- if let Some((Constant::Int(v), _)) = map
- .maybe_body_owned_by(parent_item)
- .and_then(|body_id| constant(cx, cx.tcx.typeck_body(body_id), e))
- {
+ let enclosing_body = cx.tcx.hir().local_def_id(cx.tcx.hir().enclosing_body_owner(e.hir_id));
+ if let Some((Constant::Int(v), _)) = constant(cx, cx.tcx.typeck(enclosing_body), e) {
value == v
} else {
false
PatKind::Struct(ref qpath, fields, _) => {
is_enum_variant(cx, qpath, pat.hir_id) || are_refutable(cx, fields.iter().map(|field| &*field.pat))
},
- PatKind::TupleStruct(ref qpath, pats, _) => {
- is_enum_variant(cx, qpath, pat.hir_id) || are_refutable(cx, pats)
- },
+ PatKind::TupleStruct(ref qpath, pats, _) => is_enum_variant(cx, qpath, pat.hir_id) || are_refutable(cx, pats),
PatKind::Slice(head, middle, tail) => {
match &cx.typeck_results().node_type(pat.hir_id).kind() {
rustc_ty::Slice(..) => {
// [..] is the only irrefutable slice pattern.
!head.is_empty() || middle.is_none() || !tail.is_empty()
},
- rustc_ty::Array(..) => {
- are_refutable(cx, head.iter().chain(middle).chain(tail.iter()))
- },
+ rustc_ty::Array(..) => are_refutable(cx, head.iter().chain(middle).chain(tail.iter())),
_ => {
// unreachable!()
true
matches!(item.kind, ItemKind::Mod(..)) && item.ident.name.as_str().contains("test")
}
+
+macro_rules! op_utils {
+ ($($name:ident $assign:ident)*) => {
+ /// Binary operation traits like `LangItem::Add`
+ pub static BINOP_TRAITS: &[LangItem] = &[$(LangItem::$name,)*];
+
+ /// Operator-Assign traits like `LangItem::AddAssign`
+ pub static OP_ASSIGN_TRAITS: &[LangItem] = &[$(LangItem::$assign,)*];
+
+ /// Converts `BinOpKind::Add` to `(LangItem::Add, LangItem::AddAssign)`, for example
+ pub fn binop_traits(kind: hir::BinOpKind) -> Option<(LangItem, LangItem)> {
+ match kind {
+ $(hir::BinOpKind::$name => Some((LangItem::$name, LangItem::$assign)),)*
+ _ => None,
+ }
+ }
+ };
+}
+
+op_utils! {
+ Add AddAssign
+ Sub SubAssign
+ Mul MulAssign
+ Div DivAssign
+ Rem RemAssign
+ BitXor BitXorAssign
+ BitAnd BitAndAssign
+ BitOr BitOrAssign
+ Shl ShlAssign
+ Shr ShrAssign
+}
| hir::ExprKind::Err => Sugg::NonParen(snippet),
hir::ExprKind::Assign(..) => Sugg::BinOp(AssocOp::Assign, snippet),
hir::ExprKind::AssignOp(op, ..) => Sugg::BinOp(hirbinop2assignop(op), snippet),
- hir::ExprKind::Binary(op, ..) => Sugg::BinOp(AssocOp::from_ast_binop(higher::binop(op.node)), snippet),
+ hir::ExprKind::Binary(op, ..) => Sugg::BinOp(AssocOp::from_ast_binop(op.node.into()), snippet),
hir::ExprKind::Cast(..) => Sugg::BinOp(AssocOp::As, snippet),
hir::ExprKind::Type(..) => Sugg::BinOp(AssocOp::Colon, snippet),
}
}
}
-/// Checks if the type is equal to a lang item
+/// Checks if the type is equal to a lang item.
+///
+/// Returns `false` if the `LangItem` is not defined.
pub fn is_type_lang_item(cx: &LateContext<'_>, ty: Ty<'_>, lang_item: hir::LangItem) -> bool {
match ty.kind() {
- ty::Adt(adt, _) => cx.tcx.lang_items().require(lang_item).unwrap() == adt.did,
+ ty::Adt(adt, _) => cx.tcx.lang_items().require(lang_item).map_or(false, |li| li == adt.did),
_ => false,
}
}
- [lintcheck](#lintcheck)
- [PR](#pr)
- [Common Abbreviations](#common-abbreviations)
+ - [Install from source](#install-from-source)
## Get the Code
general list can be found in the [rustc-dev-guide glossary][glossary]. Always feel free to ask if
an abbreviation or meaning is unclear to you.
+## Install from source
+
+If you are hacking on Clippy and want to install it from source, do the following:
+
+First, take note of the toolchain [override](https://rust-lang.github.io/rustup/overrides.html) in `/rust-toolchain`.
+We will use this override to install Clippy into the right toolchain.
+
+> Tip: You can view the active toolchain for the current directory with `rustup show active-toolchain`.
+
+From the Clippy project root, run the following command to build the Clippy binaries and copy them into the
+toolchain directory. This will override the currently installed Clippy component.
+
+```terminal
+cargo build --release --bin cargo-clippy --bin clippy-driver -Zunstable-options --out-dir "$(rustc --print=sysroot)/bin"
+```
+
+Now you may run `cargo clippy` in any project, using the toolchain where you just installed Clippy.
+
+```terminal
+cd my-project
+cargo +nightly-2021-07-01 clippy
+```
+
+...or `clippy-driver`
+
+```terminal
+clippy-driver +nightly-2021-07-01 <filename>
+```
+
+If you need to restore the default Clippy installation, run the following (from the Clippy project root).
+
+```terminal
+rustup component remove clippy
+rustup component add clippy
+```
+
+> **DO NOT** install using `cargo install --path . --force` since this will overwrite rustup
+[proxies](https://rust-lang.github.io/rustup/concepts/proxies.html). That is, `~/.cargo/bin/cargo-clippy` and
+`~/.cargo/bin/clippy-driver` should be hard or soft links to `~/.cargo/bin/rustup`. You can repair these by running
+`rustup update`.
+
[glossary]: https://rustc-dev-guide.rust-lang.org/appendix/glossary.html
[toolchain]
-channel = "nightly-2021-07-15"
+channel = "nightly-2021-07-19"
components = ["llvm-tools-preview", "rustc-dev", "rust-src"]
struct Foo {}
impl Foo {
- fn foo() -> Self {
+ fn new() -> Self {
impl Foo {
fn bar() {}
}
--- /dev/null
+#![allow(clippy::no_effect)]
+
+fn main() {
+ const CONSTANT: usize = 8;
+ [1; 1 % CONSTANT];
+}
--- /dev/null
+// compile-flags: -Clink-arg=-nostartfiles
+// ignore-macos
+// ignore-windows
+
+#![feature(lang_items, start, libc)]
+#![no_std]
+#![allow(clippy::redundant_pattern_matching)]
+
+use core::panic::PanicInfo;
+
+struct S;
+
+impl Drop for S {
+ fn drop(&mut self) {}
+}
+
+#[start]
+fn main(argc: isize, argv: *const *const u8) -> isize {
+ if let Some(_) = Some(S) {
+ } else {
+ }
+ 0
+}
+
+#[panic_handler]
+fn panic(_info: &PanicInfo) -> ! {
+ loop {}
+}
+
+#[lang = "eh_personality"]
+extern "C" fn eh_personality() {}
--- /dev/null
+use std::{borrow::Cow, collections::BTreeMap, marker::PhantomData, sync::Arc};
+
+fn byte_view<'a>(s: &'a ByteView<'_>) -> BTreeMap<&'a str, ByteView<'a>> {
+ panic!()
+}
+
+fn group_entries(s: &()) -> BTreeMap<Cow<'_, str>, Vec<Cow<'_, str>>> {
+ todo!()
+}
+
+struct Mmap;
+
+enum ByteViewBacking<'a> {
+ Buf(Cow<'a, [u8]>),
+ Mmap(Mmap),
+}
+
+pub struct ByteView<'a> {
+ backing: Arc<ByteViewBacking<'a>>,
+}
+
+fn main() {
+ byte_view(panic!());
+ group_entries(panic!());
+}
struct Foo;
impl Foo {
// ok
- pub async fn foo(&mut self) {}
+ pub async fn new(&mut self) -> Self {
+ Foo {}
+ }
}
// rust-lang/rust#61115
}
impl Foo {
- pub fn foo() {}
+ pub fn new() -> Self {
+ Foo { a: 0, b: 0 }
+ }
fn bar() {}
}
error: missing documentation for an associated function
--> $DIR/missing-doc-impl.rs:62:5
|
-LL | pub fn foo() {}
- | ^^^^^^^^^^^^^^^
+LL | / pub fn new() -> Self {
+LL | | Foo { a: 0, b: 0 }
+LL | | }
+ | |_____^
error: missing documentation for an associated function
- --> $DIR/missing-doc-impl.rs:63:5
+ --> $DIR/missing-doc-impl.rs:65:5
|
LL | fn bar() {}
| ^^^^^^^^^^^
error: missing documentation for an associated function
- --> $DIR/missing-doc-impl.rs:67:5
+ --> $DIR/missing-doc-impl.rs:69:5
|
LL | pub fn foo() {}
| ^^^^^^^^^^^^^^^
error: missing documentation for an associated function
- --> $DIR/missing-doc-impl.rs:71:5
+ --> $DIR/missing-doc-impl.rs:73:5
|
LL | / fn foo2() -> u32 {
LL | | 1
impl A {
// This can not be const because the type implements `Drop`.
- pub fn a(self) -> B {
+ pub fn b(self) -> B {
B
}
}
dead_code,
clippy::no_effect,
clippy::if_same_then_else,
- clippy::needless_return
+ clippy::needless_return,
+ clippy::self_named_constructor
)]
use std::cell::Cell;
dead_code,
clippy::no_effect,
clippy::if_same_then_else,
- clippy::needless_return
+ clippy::needless_return,
+ clippy::self_named_constructor
)]
use std::cell::Cell;
error: this if-then-else expression returns a bool literal
- --> $DIR/fixable.rs:39:5
+ --> $DIR/fixable.rs:40:5
|
LL | / if x {
LL | | true
= note: `-D clippy::needless-bool` implied by `-D warnings`
error: this if-then-else expression returns a bool literal
- --> $DIR/fixable.rs:44:5
+ --> $DIR/fixable.rs:45:5
|
LL | / if x {
LL | | false
| |_____^ help: you can reduce it to: `!x`
error: this if-then-else expression returns a bool literal
- --> $DIR/fixable.rs:49:5
+ --> $DIR/fixable.rs:50:5
|
LL | / if x && y {
LL | | false
| |_____^ help: you can reduce it to: `!(x && y)`
error: this if-then-else expression returns a bool literal
- --> $DIR/fixable.rs:69:5
+ --> $DIR/fixable.rs:70:5
|
LL | / if x {
LL | | return true;
| |_____^ help: you can reduce it to: `return x`
error: this if-then-else expression returns a bool literal
- --> $DIR/fixable.rs:77:5
+ --> $DIR/fixable.rs:78:5
|
LL | / if x {
LL | | return false;
| |_____^ help: you can reduce it to: `return !x`
error: this if-then-else expression returns a bool literal
- --> $DIR/fixable.rs:85:5
+ --> $DIR/fixable.rs:86:5
|
LL | / if x && y {
LL | | return true;
| |_____^ help: you can reduce it to: `return x && y`
error: this if-then-else expression returns a bool literal
- --> $DIR/fixable.rs:93:5
+ --> $DIR/fixable.rs:94:5
|
LL | / if x && y {
LL | | return false;
| |_____^ help: you can reduce it to: `return !(x && y)`
error: equality checks against true are unnecessary
- --> $DIR/fixable.rs:101:8
+ --> $DIR/fixable.rs:102:8
|
LL | if x == true {};
| ^^^^^^^^^ help: try simplifying it as shown: `x`
= note: `-D clippy::bool-comparison` implied by `-D warnings`
error: equality checks against false can be replaced by a negation
- --> $DIR/fixable.rs:105:8
+ --> $DIR/fixable.rs:106:8
|
LL | if x == false {};
| ^^^^^^^^^^ help: try simplifying it as shown: `!x`
error: equality checks against true are unnecessary
- --> $DIR/fixable.rs:115:8
+ --> $DIR/fixable.rs:116:8
|
LL | if x == true {};
| ^^^^^^^^^ help: try simplifying it as shown: `x`
error: equality checks against false can be replaced by a negation
- --> $DIR/fixable.rs:116:8
+ --> $DIR/fixable.rs:117:8
|
LL | if x == false {};
| ^^^^^^^^^^ help: try simplifying it as shown: `!x`
error: this if-then-else expression returns a bool literal
- --> $DIR/fixable.rs:125:12
+ --> $DIR/fixable.rs:126:12
|
LL | } else if returns_bool() {
| ____________^
--- /dev/null
+#![warn(clippy::self_named_constructor)]
+
+struct ShouldSpawn;
+struct ShouldNotSpawn;
+
+impl ShouldSpawn {
+ pub fn should_spawn() -> ShouldSpawn {
+ ShouldSpawn
+ }
+
+ fn should_not_spawn() -> ShouldNotSpawn {
+ ShouldNotSpawn
+ }
+}
+
+impl ShouldNotSpawn {
+ pub fn new() -> ShouldNotSpawn {
+ ShouldNotSpawn
+ }
+}
+
+struct ShouldNotSpawnWithTrait;
+
+trait ShouldNotSpawnTrait {
+ type Item;
+}
+
+impl ShouldNotSpawnTrait for ShouldNotSpawnWithTrait {
+ type Item = Self;
+}
+
+impl ShouldNotSpawnWithTrait {
+ pub fn should_not_spawn_with_trait() -> impl ShouldNotSpawnTrait<Item = Self> {
+ ShouldNotSpawnWithTrait
+ }
+}
+
+// Same trait name and same type name should not spawn the lint
+#[derive(Default)]
+pub struct Default;
+
+trait TraitSameTypeName {
+ fn should_not_spawn() -> Self;
+}
+impl TraitSameTypeName for ShouldNotSpawn {
+ fn should_not_spawn() -> Self {
+ ShouldNotSpawn
+ }
+}
+
+struct SelfMethodShouldNotSpawn;
+
+impl SelfMethodShouldNotSpawn {
+ fn self_method_should_not_spawn(self) -> Self {
+ SelfMethodShouldNotSpawn
+ }
+}
+
+fn main() {}
--- /dev/null
+error: constructor `should_spawn` has the same name as the type
+ --> $DIR/self_named_constructor.rs:7:5
+ |
+LL | / pub fn should_spawn() -> ShouldSpawn {
+LL | | ShouldSpawn
+LL | | }
+ | |_____^
+ |
+ = note: `-D clippy::self-named-constructor` implied by `-D warnings`
+
+error: aborting due to previous error
+
-error: suspicious use of binary operator in `Add` impl
+error: suspicious use of `-` in `Add` impl
--> $DIR/suspicious_arithmetic_impl.rs:13:20
|
LL | Foo(self.0 - other.0)
|
= note: `-D clippy::suspicious-arithmetic-impl` implied by `-D warnings`
-error: suspicious use of binary operator in `AddAssign` impl
+error: suspicious use of `-` in `AddAssign` impl
--> $DIR/suspicious_arithmetic_impl.rs:19:23
|
LL | *self = *self - other;
|
= note: `-D clippy::suspicious-op-assign-impl` implied by `-D warnings`
-error: suspicious use of binary operator in `MulAssign` impl
+error: suspicious use of `/` in `MulAssign` impl
--> $DIR/suspicious_arithmetic_impl.rs:32:16
|
LL | self.0 /= other.0;
| ^^
-error: suspicious use of binary operator in `Rem` impl
+error: suspicious use of `/` in `Rem` impl
--> $DIR/suspicious_arithmetic_impl.rs:70:20
|
LL | Foo(self.0 / other.0)
| ^
-error: suspicious use of binary operator in `BitAnd` impl
+error: suspicious use of `|` in `BitAnd` impl
--> $DIR/suspicious_arithmetic_impl.rs:78:20
|
LL | Foo(self.0 | other.0)
| ^
-error: suspicious use of binary operator in `BitOr` impl
+error: suspicious use of `^` in `BitOr` impl
--> $DIR/suspicious_arithmetic_impl.rs:86:20
|
LL | Foo(self.0 ^ other.0)
| ^
-error: suspicious use of binary operator in `BitXor` impl
+error: suspicious use of `&` in `BitXor` impl
--> $DIR/suspicious_arithmetic_impl.rs:94:20
|
LL | Foo(self.0 & other.0)
| ^
-error: suspicious use of binary operator in `Shl` impl
+error: suspicious use of `>>` in `Shl` impl
--> $DIR/suspicious_arithmetic_impl.rs:102:20
|
LL | Foo(self.0 >> other.0)
| ^^
-error: suspicious use of binary operator in `Shr` impl
+error: suspicious use of `<<` in `Shr` impl
--> $DIR/suspicious_arithmetic_impl.rs:110:20
|
LL | Foo(self.0 << other.0)
clippy::unused_unit,
clippy::unnecessary_wraps,
clippy::or_fun_call,
- clippy::needless_question_mark
+ clippy::needless_question_mark,
+ clippy::self_named_constructor
)]
use std::fmt::Debug;
error: passing a unit value to a function
- --> $DIR/unit_arg.rs:55:5
+ --> $DIR/unit_arg.rs:56:5
|
LL | / foo({
LL | | 1;
|
error: passing a unit value to a function
- --> $DIR/unit_arg.rs:58:5
+ --> $DIR/unit_arg.rs:59:5
|
LL | foo(foo(1));
| ^^^^^^^^^^^
|
error: passing a unit value to a function
- --> $DIR/unit_arg.rs:59:5
+ --> $DIR/unit_arg.rs:60:5
|
LL | / foo({
LL | | foo(1);
|
error: passing a unit value to a function
- --> $DIR/unit_arg.rs:64:5
+ --> $DIR/unit_arg.rs:65:5
|
LL | / b.bar({
LL | | 1;
|
error: passing unit values to a function
- --> $DIR/unit_arg.rs:67:5
+ --> $DIR/unit_arg.rs:68:5
|
LL | taking_multiple_units(foo(0), foo(1));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
error: passing unit values to a function
- --> $DIR/unit_arg.rs:68:5
+ --> $DIR/unit_arg.rs:69:5
|
LL | / taking_multiple_units(foo(0), {
LL | | foo(1);
|
error: passing unit values to a function
- --> $DIR/unit_arg.rs:72:5
+ --> $DIR/unit_arg.rs:73:5
|
LL | / taking_multiple_units(
LL | | {
...
error: passing a unit value to a function
- --> $DIR/unit_arg.rs:83:13
+ --> $DIR/unit_arg.rs:84:13
|
LL | None.or(Some(foo(2)));
| ^^^^^^^^^^^^
|
error: passing a unit value to a function
- --> $DIR/unit_arg.rs:86:5
+ --> $DIR/unit_arg.rs:87:5
|
LL | foo(foo(()));
| ^^^^^^^^^^^^
|
error: passing a unit value to a function
- --> $DIR/unit_arg.rs:123:5
+ --> $DIR/unit_arg.rs:124:5
|
LL | Some(foo(1))
| ^^^^^^^^^^^^
#![warn(clippy::use_self)]
#![allow(dead_code)]
-#![allow(clippy::should_implement_trait, clippy::upper_case_acronyms, clippy::from_over_into)]
+#![allow(
+ clippy::should_implement_trait,
+ clippy::upper_case_acronyms,
+ clippy::from_over_into,
+ clippy::self_named_constructor
+)]
#[macro_use]
extern crate proc_macro_derive;
#![warn(clippy::use_self)]
#![allow(dead_code)]
-#![allow(clippy::should_implement_trait, clippy::upper_case_acronyms, clippy::from_over_into)]
+#![allow(
+ clippy::should_implement_trait,
+ clippy::upper_case_acronyms,
+ clippy::from_over_into,
+ clippy::self_named_constructor
+)]
#[macro_use]
extern crate proc_macro_derive;
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:18:21
+ --> $DIR/use_self.rs:23:21
|
LL | fn new() -> Foo {
| ^^^ help: use the applicable keyword: `Self`
= note: `-D clippy::use-self` implied by `-D warnings`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:19:13
+ --> $DIR/use_self.rs:24:13
|
LL | Foo {}
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:21:22
+ --> $DIR/use_self.rs:26:22
|
LL | fn test() -> Foo {
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:22:13
+ --> $DIR/use_self.rs:27:13
|
LL | Foo::new()
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:27:25
+ --> $DIR/use_self.rs:32:25
|
LL | fn default() -> Foo {
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:28:13
+ --> $DIR/use_self.rs:33:13
|
LL | Foo::new()
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:93:24
+ --> $DIR/use_self.rs:98:24
|
LL | fn bad(foos: &[Foo]) -> impl Iterator<Item = &Foo> {
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:93:55
+ --> $DIR/use_self.rs:98:55
|
LL | fn bad(foos: &[Foo]) -> impl Iterator<Item = &Foo> {
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:108:13
+ --> $DIR/use_self.rs:113:13
|
LL | TS(0)
| ^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:143:29
+ --> $DIR/use_self.rs:148:29
|
LL | fn bar() -> Bar {
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:144:21
+ --> $DIR/use_self.rs:149:21
|
LL | Bar { foo: Foo {} }
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:155:21
+ --> $DIR/use_self.rs:160:21
|
LL | fn baz() -> Foo {
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:156:13
+ --> $DIR/use_self.rs:161:13
|
LL | Foo {}
| ^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:173:21
+ --> $DIR/use_self.rs:178:21
|
LL | let _ = Enum::B(42);
| ^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:174:21
+ --> $DIR/use_self.rs:179:21
|
LL | let _ = Enum::C { field: true };
| ^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:175:21
+ --> $DIR/use_self.rs:180:21
|
LL | let _ = Enum::A;
| ^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:217:13
+ --> $DIR/use_self.rs:222:13
|
LL | nested::A::fun_1();
| ^^^^^^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:218:13
+ --> $DIR/use_self.rs:223:13
|
LL | nested::A::A;
| ^^^^^^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:220:13
+ --> $DIR/use_self.rs:225:13
|
LL | nested::A {};
| ^^^^^^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:239:13
+ --> $DIR/use_self.rs:244:13
|
LL | TestStruct::from_something()
| ^^^^^^^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:253:25
+ --> $DIR/use_self.rs:258:25
|
LL | async fn g() -> S {
| ^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:254:13
+ --> $DIR/use_self.rs:259:13
|
LL | S {}
| ^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:258:16
+ --> $DIR/use_self.rs:263:16
|
LL | &p[S::A..S::B]
| ^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:258:22
+ --> $DIR/use_self.rs:263:22
|
LL | &p[S::A..S::B]
| ^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:281:29
+ --> $DIR/use_self.rs:286:29
|
LL | fn foo(value: T) -> Foo<T> {
| ^^^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:282:13
+ --> $DIR/use_self.rs:287:13
|
LL | Foo::<T> { value }
| ^^^^^^^^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:454:13
+ --> $DIR/use_self.rs:459:13
|
LL | A::new::<submod::B>(submod::B {})
| ^ help: use the applicable keyword: `Self`
error: unnecessary structure name repetition
- --> $DIR/use_self.rs:491:13
+ --> $DIR/use_self.rs:496:13
|
LL | S2::new()
| ^^ help: use the applicable keyword: `Self`
-Subproject commit 250eff85c86b089b77005691b899cea739f7e0cb
+Subproject commit e2872a3f2a26154b91a6a6085d56016509803c61
-Subproject commit fe00358888a24c64878abc15f09b0e60e16db9d6
+Subproject commit ea105f9396a9dab68e71efb06016b7c76c83ba7c