+Version 1.66.0 (2022-12-15)
+==========================
+
+Language
+--------
+- [Permit specifying explicit discriminants on all `repr(Int)` enums](https://github.com/rust-lang/rust/pull/95710/)
+ ```rust
+ #[repr(u8)]
+ enum Foo {
+ A(u8) = 0,
+ B(i8) = 1,
+ C(bool) = 42,
+ }
+ ```
+- [Allow transmutes between the same type differing only in lifetimes](https://github.com/rust-lang/rust/pull/101520/)
+- [Change constant evaluation errors from a deny-by-default lint to a hard error](https://github.com/rust-lang/rust/pull/102091/)
+- [Trigger `must_use` on `impl Trait` for supertraits](https://github.com/rust-lang/rust/pull/102287/)
+ This makes `impl ExactSizeIterator` respect the existing `#[must_use]` annotation on `Iterator`.
+- [Allow `..X` and `..=X` in patterns](https://github.com/rust-lang/rust/pull/102275/)
+- [Uplift `clippy::for_loops_over_fallibles` lint into rustc](https://github.com/rust-lang/rust/pull/99696/)
+- [Stabilize `sym` operands in inline assembly](https://github.com/rust-lang/rust/pull/103168/)
+- [Update to Unicode 15](https://github.com/rust-lang/rust/pull/101912/)
+- [Opaque types no longer imply lifetime bounds](https://github.com/rust-lang/rust/pull/95474/)
+ This is a soundness fix which may break code that was erroneously relying on this behavior.
+
+Compiler
+--------
+- [Add armv5te-none-eabi and thumbv5te-none-eabi tier 3 targets](https://github.com/rust-lang/rust/pull/101329/)
+ - Refer to Rust's [platform support page][platform-support-doc] for more
+ information on Rust's tiered platform support.
+- [Add support for linking against macOS universal libraries](https://github.com/rust-lang/rust/pull/98736)
+
+Libraries
+---------
+- [Fix `#[derive(Default)]` on a generic `#[default]` enum adding unnecessary `Default` bounds](https://github.com/rust-lang/rust/pull/101040/)
+- [Update to Unicode 15](https://github.com/rust-lang/rust/pull/101821/)
+
+Stabilized APIs
+---------------
+
+- [`proc_macro::Span::source_text`](https://doc.rust-lang.org/stable/proc_macro/struct.Span.html#method.source_text)
+- [`uX::{checked_add_signed, overflowing_add_signed, saturating_add_signed, wrapping_add_signed}`](https://doc.rust-lang.org/stable/std/primitive.u8.html#method.checked_add_signed)
+- [`iX::{checked_add_unsigned, overflowing_add_unsigned, saturating_add_unsigned, wrapping_add_unsigned}`](https://doc.rust-lang.org/stable/std/primitive.i8.html#method.checked_add_unsigned)
+- [`iX::{checked_sub_unsigned, overflowing_sub_unsigned, saturating_sub_unsigned, wrapping_sub_unsigned}`](https://doc.rust-lang.org/stable/std/primitive.i8.html#method.checked_sub_unsigned)
+- [`BTreeSet::{first, last, pop_first, pop_last}`](https://doc.rust-lang.org/stable/std/collections/struct.BTreeSet.html#method.first)
+- [`BTreeMap::{first_key_value, last_key_value, first_entry, last_entry, pop_first, pop_last}`](https://doc.rust-lang.org/stable/std/collections/struct.BTreeMap.html#method.first_key_value)
+- [Add `AsFd` implementations for stdio lock types on WASI.](https://github.com/rust-lang/rust/pull/101768/)
+- [`impl TryFrom<Vec<T>> for Box<[T; N]>`](https://doc.rust-lang.org/stable/std/boxed/struct.Box.html#impl-TryFrom%3CVec%3CT%2C%20Global%3E%3E-for-Box%3C%5BT%3B%20N%5D%2C%20Global%3E)
+- [`core::hint::black_box`](https://doc.rust-lang.org/stable/std/hint/fn.black_box.html)
+- [`Duration::try_from_secs_{f32,f64}`](https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.try_from_secs_f32)
+- [`Option::unzip`](https://doc.rust-lang.org/stable/std/option/enum.Option.html#method.unzip)
+- [`std::os::fd`](https://doc.rust-lang.org/stable/std/os/fd/index.html)
+
+
+Rustdoc
+-------
+
+- [Add Rustdoc warning for invalid HTML tags in the documentation](https://github.com/rust-lang/rust/pull/101720/)
+
+Cargo
+-----
+
+- [Added `cargo remove` to remove dependencies from Cargo.toml](https://doc.rust-lang.org/nightly/cargo/commands/cargo-remove.html)
+- [`cargo publish` now waits for the new version to be downloadable before exiting](https://github.com/rust-lang/cargo/pull/11062)
+
+See [detailed release notes](https://github.com/rust-lang/cargo/blob/master/CHANGELOG.md#cargo-166-2022-12-15) for more.
+
+Compatibility Notes
+-------------------
+
+- [Only apply `ProceduralMasquerade` hack to older versions of `rental`](https://github.com/rust-lang/rust/pull/94063/)
+- [Don't export `__heap_base` and `__data_end` on wasm32-wasi.](https://github.com/rust-lang/rust/pull/102385/)
+- [Don't export `__wasm_init_memory` on WebAssembly.](https://github.com/rust-lang/rust/pull/102426/)
+- [Only export `__tls_*` on wasm32-unknown-unknown.](https://github.com/rust-lang/rust/pull/102440/)
+- [Don't link to `libresolv` in libstd on Darwin](https://github.com/rust-lang/rust/pull/102766/)
+- [Update libstd's libc to 0.2.135 (to make `libstd` no longer pull in `libiconv.dylib` on Darwin)](https://github.com/rust-lang/rust/pull/103277/)
+- [Opaque types no longer imply lifetime bounds](https://github.com/rust-lang/rust/pull/95474/)
+ This is a soundness fix which may break code that was erroneously relying on this behavior.
+- [Make `order_dependent_trait_objects` show up in future-breakage reports](https://github.com/rust-lang/rust/pull/102635/)
+- [Change std::process::Command spawning to default to inheriting the parent's signal mask](https://github.com/rust-lang/rust/pull/101077/)
+
+Internal Changes
+----------------
+
+These changes do not affect any public interfaces of Rust, but they represent
+significant improvements to the performance or internals of rustc and related
+tools.
+
+- [Enable BOLT for LLVM compilation](https://github.com/rust-lang/rust/pull/94381/)
+- [Enable LTO for rustc_driver.so](https://github.com/rust-lang/rust/pull/101403/)
+
Version 1.65.0 (2022-11-03)
==========================
pub fn for_align<C: HasDataLayout>(cx: &C, wanted: Align) -> Option<Integer> {
let dl = cx.data_layout();
- for candidate in [I8, I16, I32, I64, I128] {
- if wanted == candidate.align(dl).abi && wanted.bytes() == candidate.size().bytes() {
- return Some(candidate);
- }
- }
- None
+ [I8, I16, I32, I64, I128].into_iter().find(|&candidate| {
+ wanted == candidate.align(dl).abi && wanted.bytes() == candidate.size().bytes()
+ })
}
/// Find the largest integer with the given alignment or less.
if let NtExpr(expr) | NtLiteral(expr) = &**nt
&& let ast::ExprKind::Lit(token_lit) = expr.kind =>
{
- Some(token_lit.clone())
+ Some(token_lit)
}
_ => None,
}
{
let spans = vec![f1_span, f2_span];
sess.struct_span_err(
- spans.clone(),
+ spans,
&format!(
"features `{}` and `{}` are incompatible, using them at the same time \
is not allowed",
err.span_suggestion_verbose(
span.shrink_to_hi(),
"consider cloning the value if the performance cost is acceptable",
- ".clone()".to_string(),
+ ".clone()",
Applicability::MachineApplicable,
);
}
(item, true, ecx.with_def_site_ctxt(fn_kind.sig.span))
} else {
ecx.sess.parse_sess.span_diagnostic.span_err(item.span(), "alloc_error_handler must be a function");
- return vec![orig_item.clone()];
+ return vec![orig_item];
};
// Generate a bunch of new items using the AllocFnFactory
}
}
if !missing_literals.is_empty() {
- let mut err = cx.struct_span_err(missing_literals.clone(), "expected a byte literal");
+ let mut err = cx.struct_span_err(missing_literals, "expected a byte literal");
err.note("only byte literals (like `b\"foo\"`, `b's'`, and `[3, 4, 5]`) can be passed to `concat_bytes!()`");
err.emit();
return base::MacEager::expr(DummyResult::raw_expr(sp, true));
// TODO(antoyo)
}
- fn cleanup_landing_pad(&mut self, _ty: Type<'gcc>, _pers_fn: RValue<'gcc>) -> RValue<'gcc> {
- let field1 = self.context.new_field(None, self.u8_type.make_pointer(), "landing_pad_field_1");
- let field2 = self.context.new_field(None, self.i32_type, "landing_pad_field_1");
- let struct_type = self.context.new_struct_type(None, "landing_pad", &[field1, field2]);
- self.current_func().new_local(None, struct_type.as_type(), "landing_pad")
- .to_rvalue()
+ fn cleanup_landing_pad(&mut self, _pers_fn: RValue<'gcc>) -> (RValue<'gcc>, RValue<'gcc>) {
+ (
+ self.current_func().new_local(None, self.u8_type.make_pointer(), "landing_pad0")
+ .to_rvalue(),
+ self.current_func().new_local(None, self.i32_type, "landing_pad1").to_rvalue(),
+ )
// TODO(antoyo): Properly implement unwinding.
// the above is just to make the compilation work as it seems
// rustc_codegen_ssa now calls the unwinding builder methods even on panic=abort.
}
- fn resume(&mut self, _exn: RValue<'gcc>) {
+ fn resume(&mut self, _exn0: RValue<'gcc>, _exn1: RValue<'gcc>) {
// TODO(bjorn3): Properly implement unwinding.
self.unreachable();
}
}
pub(crate) fn prepare_thin(module: ModuleCodegen<ModuleLlvm>) -> (String, ThinBuffer) {
- let name = module.name.clone();
+ let name = module.name;
let buffer = ThinBuffer::new(module.module_llvm.llmod(), true);
(name, buffer)
}
}
}
- fn cleanup_landing_pad(&mut self, ty: &'ll Type, pers_fn: &'ll Value) -> &'ll Value {
+ fn cleanup_landing_pad(&mut self, pers_fn: &'ll Value) -> (&'ll Value, &'ll Value) {
+ let ty = self.type_struct(&[self.type_i8p(), self.type_i32()], false);
let landing_pad = self.landing_pad(ty, pers_fn, 1 /* FIXME should this be 0? */);
unsafe {
llvm::LLVMSetCleanup(landing_pad, llvm::True);
}
- landing_pad
+ (self.extract_value(landing_pad, 0), self.extract_value(landing_pad, 1))
}
- fn resume(&mut self, exn: &'ll Value) {
+ fn resume(&mut self, exn0: &'ll Value, exn1: &'ll Value) {
+ let ty = self.type_struct(&[self.type_i8p(), self.type_i32()], false);
+ let mut exn = self.const_undef(ty);
+ exn = self.insert_value(exn, exn0, 0);
+ exn = self.insert_value(exn, exn1, 1);
unsafe {
llvm::LLVMBuildResume(self.llbuilder, exn);
}
typeid: &'ll Value,
) -> Self::Value {
let vtable_byte_offset = self.const_i32(vtable_byte_offset as i32);
- self.call_intrinsic("llvm.type.checked.load", &[llvtable, vtable_byte_offset, typeid])
+ let type_checked_load =
+ self.call_intrinsic("llvm.type.checked.load", &[llvtable, vtable_byte_offset, typeid]);
+ self.extract_value(type_checked_load, 0)
}
fn va_start(&mut self, va_list: &'ll Value) -> &'ll Value {
let typeid =
bx.typeid_metadata(typeid_for_trait_ref(bx.tcx(), expect_dyn_trait_in_self(ty)));
let vtable_byte_offset = self.0 * bx.data_layout().pointer_size.bytes();
- let type_checked_load = bx.type_checked_load(llvtable, vtable_byte_offset, typeid);
- let func = bx.extract_value(type_checked_load, 0);
+ let func = bx.type_checked_load(llvtable, vtable_byte_offset, typeid);
bx.pointercast(func, llty)
} else {
let ptr_align = bx.tcx().data_layout.pointer_align.abi;
bx.cleanup_ret(funclet, None);
} else {
let slot = self.get_personality_slot(bx);
- let lp0 = slot.project_field(bx, 0);
- let lp0 = bx.load_operand(lp0).immediate();
- let lp1 = slot.project_field(bx, 1);
- let lp1 = bx.load_operand(lp1).immediate();
+ let exn0 = slot.project_field(bx, 0);
+ let exn0 = bx.load_operand(exn0).immediate();
+ let exn1 = slot.project_field(bx, 1);
+ let exn1 = bx.load_operand(exn1).immediate();
slot.storage_dead(bx);
- let mut lp = bx.const_undef(self.landing_pad_type());
- lp = bx.insert_value(lp, lp0, 0);
- lp = bx.insert_value(lp, lp1, 1);
- bx.resume(lp);
+ bx.resume(exn0, exn1);
}
}
let mut cleanup_bx = Bx::build(self.cx, cleanup_llbb);
let llpersonality = self.cx.eh_personality();
- let llretty = self.landing_pad_type();
- let lp = cleanup_bx.cleanup_landing_pad(llretty, llpersonality);
+ let (exn0, exn1) = cleanup_bx.cleanup_landing_pad(llpersonality);
let slot = self.get_personality_slot(&mut cleanup_bx);
slot.storage_live(&mut cleanup_bx);
- Pair(cleanup_bx.extract_value(lp, 0), cleanup_bx.extract_value(lp, 1))
- .store(&mut cleanup_bx, slot);
+ Pair(exn0, exn1).store(&mut cleanup_bx, slot);
cleanup_bx.br(llbb);
cleanup_llbb
}
}
- fn landing_pad_type(&self) -> Bx::Type {
- let cx = self.cx;
- cx.type_struct(&[cx.type_i8p(), cx.type_i32()], false)
- }
-
fn unreachable_block(&mut self) -> Bx::BasicBlock {
self.unreachable_block.unwrap_or_else(|| {
let llbb = Bx::append_block(self.cx, self.llfn, "unreachable");
self.set_debug_loc(&mut bx, mir::SourceInfo::outermost(self.mir.span));
let llpersonality = self.cx.eh_personality();
- let llretty = self.landing_pad_type();
- bx.cleanup_landing_pad(llretty, llpersonality);
+ bx.cleanup_landing_pad(llpersonality);
let (fn_abi, fn_ptr) = common::build_langcall(&bx, None, LangItem::PanicNoUnwind);
let fn_ty = bx.fn_decl_backend_type(&fn_abi);
assert!(bx.cx().tcx().is_static(def_id));
let static_ = bx.get_static(def_id);
let layout = bx.layout_of(bx.cx().tcx().static_ptr_ty(def_id));
- OperandRef::from_immediate_or_packed_pair(bx, static_, layout)
+ OperandRef { val: OperandValue::Immediate(static_), layout }
}
mir::Rvalue::Use(ref operand) => self.codegen_operand(bx, operand),
mir::Rvalue::Repeat(..) | mir::Rvalue::Aggregate(..) => {
fn set_personality_fn(&mut self, personality: Self::Value);
// These are used by everyone except msvc
- fn cleanup_landing_pad(&mut self, ty: Self::Type, pers_fn: Self::Value) -> Self::Value;
- fn resume(&mut self, exn: Self::Value);
+ fn cleanup_landing_pad(&mut self, pers_fn: Self::Value) -> (Self::Value, Self::Value);
+ fn resume(&mut self, exn0: Self::Value, exn1: Self::Value);
// These are used only by msvc
fn cleanup_pad(&mut self, parent: Option<Self::Value>, args: &[Self::Value]) -> Self::Funclet;
pub const ALPHANUMERIC_ONLY: usize = 62;
pub const CASE_INSENSITIVE: usize = 36;
-const BASE_64: &[u8; MAX_BASE as usize] =
+const BASE_64: &[u8; MAX_BASE] =
b"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@$";
#[inline]
self.set_span(after);
for span_label in before.span_labels() {
if let Some(label) = span_label.label {
- self.span.push_span_label(after, label);
+ if span_label.is_primary {
+ self.span.push_span_label(after, label);
+ } else {
+ self.span.push_span_label(span_label.span, label);
+ }
}
}
self
debug_assert!(
!(suggestions
.iter()
- .flat_map(|suggs| suggs)
+ .flatten()
.any(|(sp, suggestion)| sp.is_empty() && suggestion.is_empty())),
"Span must not be empty and have no suggestion"
);
// see how it *looks* with
// very *weird* formats
// see?
- for &(ref text, ref style) in msg.iter() {
+ for (text, style) in msg.iter() {
let text = self.translate_message(text, args);
let lines = text.split('\n').collect::<Vec<_>>();
if lines.len() > 1 {
buffer.append(0, ": ", header_style);
label_width += 2;
}
- for &(ref text, _) in msg.iter() {
+ for (text, _) in msg.iter() {
let text = self.translate_message(text, args);
// Account for newlines to align output to its label.
for (line, text) in normalize_whitespace(&text).lines().enumerate() {
}
pub fn get_named(&self, name: Symbol) -> Option<&GenericParam<'hir>> {
- for param in self.params {
- if name == param.name.ident().name {
- return Some(param);
- }
- }
- None
+ self.params.iter().find(|¶m| name == param.name.ident().name)
}
pub fn spans(&self) -> MultiSpan {
self.words[start_word_index] |= !(start_mask - 1);
// And all trailing bits (i.e. from 0..=end) in the end word,
// including the end.
- self.words[end_word_index] |= end_mask | end_mask - 1;
+ self.words[end_word_index] |= end_mask | (end_mask - 1);
} else {
self.words[start_word_index] |= end_mask | (end_mask - start_mask);
}
where
T: Relate<'tcx>,
{
+ // A binder is equal to itself if it's structually equal to itself
+ if a == b {
+ return Ok(a);
+ }
+
if a.skip_binder().has_escaping_bound_vars() || b.skip_binder().has_escaping_bound_vars() {
self.fields.higher_ranked_sub(a, b, self.a_is_expected)?;
self.fields.higher_ranked_sub(b, a, self.a_is_expected)?;
Applicability::MaybeIncorrect,
);
}
- if let Some((param_span, param_ty)) = param.clone() {
+ if let Some((param_span, ref param_ty)) = param {
err.span_suggestion_verbose(
param_span,
add_static_bound,
where
T: Relate<'tcx>,
{
+ // GLB of a binder and itself is just itself
+ if a == b {
+ return Ok(a);
+ }
+
debug!("binders(a={:?}, b={:?})", a, b);
if a.skip_binder().has_escaping_bound_vars() || b.skip_binder().has_escaping_bound_vars() {
// When higher-ranked types are involved, computing the GLB is
where
T: Relate<'tcx>,
{
+ // LUB of a binder and itself is just itself
+ if a == b {
+ return Ok(a);
+ }
+
debug!("binders(a={:?}, b={:?})", a, b);
if a.skip_binder().has_escaping_bound_vars() || b.skip_binder().has_escaping_bound_vars() {
// When higher-ranked types are involved, computing the LUB is
where
T: Relate<'tcx>,
{
+ // A binder is always a subtype of itself if it's structually equal to itself
+ if a == b {
+ return Ok(a);
+ }
+
self.fields.higher_ranked_sub(a, b, self.a_is_expected)?;
Ok(a)
}
})?;
}
Some(c) => {
- let digit =
+ let digit: u32 =
c.to_digit(16).ok_or(EscapeError::InvalidCharInUnicodeEscape)?;
n_digits += 1;
if n_digits > 6 {
// Stop updating value since we're sure that it's incorrect already.
continue;
}
- let digit = digit as u32;
value = value * 16 + digit;
}
};
declare_lint! {
/// The `trivial_casts` lint detects trivial casts which could be replaced
- /// with coercion, which may require [type ascription] or a temporary
- /// variable.
+ /// with coercion, which may require a temporary variable.
///
/// ### Example
///
/// with FFI interfaces or complex type aliases, where it triggers
/// incorrectly, or in situations where it will be more difficult to
/// clearly express the intent. It may be possible that this will become a
- /// warning in the future, possibly with [type ascription] providing a
- /// convenient way to work around the current issues. See [RFC 401] for
- /// historical context.
- ///
- /// [type ascription]: https://github.com/rust-lang/rust/issues/23416
- /// [RFC 401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md
+ /// warning in the future, possibly with an explicit syntax for coercions
+ /// providing a convenient way to work around the current issues.
+ /// See [RFC 401 (coercions)][rfc-401], [RFC 803 (type ascription)][rfc-803] and
+ /// [RFC 3307 (remove type ascription)][rfc-3307] for historical context.
+ ///
+ /// [rfc-401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md
+ /// [rfc-803]: https://github.com/rust-lang/rfcs/blob/master/text/0803-type-ascription.md
+ /// [rfc-3307]: https://github.com/rust-lang/rfcs/blob/master/text/3307-de-rfc-type-ascription.md
pub TRIVIAL_CASTS,
Allow,
"detects trivial casts which could be removed"
/// with FFI interfaces or complex type aliases, where it triggers
/// incorrectly, or in situations where it will be more difficult to
/// clearly express the intent. It may be possible that this will become a
- /// warning in the future, possibly with [type ascription] providing a
- /// convenient way to work around the current issues. See [RFC 401] for
- /// historical context.
- ///
- /// [type ascription]: https://github.com/rust-lang/rust/issues/23416
- /// [RFC 401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md
+ /// warning in the future, possibly with an explicit syntax for coercions
+ /// providing a convenient way to work around the current issues.
+ /// See [RFC 401 (coercions)][rfc-401], [RFC 803 (type ascription)][rfc-803] and
+ /// [RFC 3307 (remove type ascription)][rfc-3307] for historical context.
+ ///
+ /// [rfc-401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md
+ /// [rfc-803]: https://github.com/rust-lang/rfcs/blob/master/text/0803-type-ascription.md
+ /// [rfc-3307]: https://github.com/rust-lang/rfcs/blob/master/text/3307-de-rfc-type-ascription.md
pub TRIVIAL_NUMERIC_CASTS,
Allow,
"detects trivial casts of numeric types which could be removed"
}
let mut short;
loop {
- // Look for the longest properly trimmed path that still fits in lenght_limit.
+ // Look for the longest properly trimmed path that still fits in length_limit.
short = with_forced_trimmed_paths!(
FmtPrinter::new_with_limit(
self,
pub predicates: Vec<Predicate<'tcx>>,
}
-#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable)]
+#[derive(Copy, Clone, PartialEq, Eq, Debug, TypeFoldable, TypeVisitable)]
pub enum ImplSubject<'tcx> {
Trait(TraitRef<'tcx>),
Inherent(Ty<'tcx>),
T: Relate<'tcx>;
}
-pub trait Relate<'tcx>: TypeFoldable<'tcx> + Copy {
+pub trait Relate<'tcx>: TypeFoldable<'tcx> + PartialEq + Copy {
fn relate<R: TypeRelation<'tcx>>(
relation: &mut R,
a: Self,
}
}
-#[derive(Copy, Debug, Clone, TypeFoldable, TypeVisitable)]
+#[derive(PartialEq, Copy, Debug, Clone, TypeFoldable, TypeVisitable)]
struct GeneratorWitness<'tcx>(&'tcx ty::List<Ty<'tcx>>);
impl<'tcx> Relate<'tcx> for GeneratorWitness<'tcx> {
/// * `GR`: The "return type", which is the type of value returned upon
/// completion of the generator.
/// * `GW`: The "generator witness".
-#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, Lift)]
+#[derive(Copy, Clone, PartialEq, Eq, Debug, TypeFoldable, TypeVisitable, Lift)]
pub struct ClosureSubsts<'tcx> {
/// Lifetime and type parameters from the enclosing function,
/// concatenated with a tuple containing the types of the upvars.
}
/// Similar to `ClosureSubsts`; see the above documentation for more.
-#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, Lift)]
+#[derive(Copy, Clone, PartialEq, Eq, Debug, TypeFoldable, TypeVisitable, Lift)]
pub struct GeneratorSubsts<'tcx> {
pub substs: SubstsRef<'tcx>,
}
impl<'a, 'tcx> Builder<'a, 'tcx> {
/// Builds a block of MIR statements to evaluate the THIR `expr`.
- /// If the original expression was an AST statement,
- /// (e.g., `some().code(&here());`) then `opt_stmt_span` is the
- /// span of that statement (including its semicolon, if any).
- /// The scope is used if a statement temporary must be dropped.
+ ///
+ /// The `statement_scope` is used if a statement temporary must be dropped.
pub(crate) fn stmt_expr(
&mut self,
mut block: BasicBlock,
None
}
-/// When enumerating the child fragments of a path, don't recurse into
-/// paths (1.) past arrays, slices, and pointers, nor (2.) into a type
-/// that implements `Drop`.
-///
-/// Places behind references or arrays are not tracked by elaboration
-/// and are always assumed to be initialized when accessible. As
-/// references and indexes can be reseated, trying to track them can
-/// only lead to trouble.
-///
-/// Places behind ADT's with a Drop impl are not tracked by
-/// elaboration since they can never have a drop-flag state that
-/// differs from that of the parent with the Drop impl.
-///
-/// In both cases, the contents can only be accessed if and only if
-/// their parents are initialized. This implies for example that there
-/// is no need to maintain separate drop flags to track such state.
-//
-// FIXME: we have to do something for moving slice patterns.
-fn place_contents_drop_state_cannot_differ<'tcx>(
- tcx: TyCtxt<'tcx>,
- body: &Body<'tcx>,
- place: mir::Place<'tcx>,
-) -> bool {
- let ty = place.ty(body, tcx).ty;
- match ty.kind() {
- ty::Array(..) => {
- debug!(
- "place_contents_drop_state_cannot_differ place: {:?} ty: {:?} => false",
- place, ty
- );
- false
- }
- ty::Slice(..) | ty::Ref(..) | ty::RawPtr(..) => {
- debug!(
- "place_contents_drop_state_cannot_differ place: {:?} ty: {:?} refd => true",
- place, ty
- );
- true
- }
- ty::Adt(def, _) if (def.has_dtor(tcx) && !def.is_box()) || def.is_union() => {
- debug!(
- "place_contents_drop_state_cannot_differ place: {:?} ty: {:?} Drop => true",
- place, ty
- );
- true
- }
- _ => false,
- }
-}
-
pub fn on_lookup_result_bits<'tcx, F>(
tcx: TyCtxt<'tcx>,
body: &Body<'tcx>,
) where
F: FnMut(MovePathIndex),
{
+ #[inline]
fn is_terminal_path<'tcx>(
tcx: TyCtxt<'tcx>,
body: &Body<'tcx>,
move_data: &MoveData<'tcx>,
path: MovePathIndex,
) -> bool {
- place_contents_drop_state_cannot_differ(tcx, body, move_data.move_paths[path].place)
+ let place = move_data.move_paths[path].place;
+
+ // When enumerating the child fragments of a path, don't recurse into
+ // paths (1.) past arrays, slices, and pointers, nor (2.) into a type
+ // that implements `Drop`.
+ //
+ // Places behind references or arrays are not tracked by elaboration
+ // and are always assumed to be initialized when accessible. As
+ // references and indexes can be reseated, trying to track them can
+ // only lead to trouble.
+ //
+ // Places behind ADT's with a Drop impl are not tracked by
+ // elaboration since they can never have a drop-flag state that
+ // differs from that of the parent with the Drop impl.
+ //
+ // In both cases, the contents can only be accessed if and only if
+ // their parents are initialized. This implies for example that there
+ // is no need to maintain separate drop flags to track such state.
+ //
+ // FIXME: we have to do something for moving slice patterns.
+ let ty = place.ty(body, tcx).ty;
+ match ty.kind() {
+ ty::Adt(def, _) if (def.has_dtor(tcx) && !def.is_box()) || def.is_union() => {
+ debug!(
+ "place_contents_drop_state_cannot_differ place: {:?} ty: {:?} Drop => true",
+ place, ty
+ );
+ true
+ }
+ ty::Array(..) => {
+ debug!(
+ "place_contents_drop_state_cannot_differ place: {:?} ty: {:?} => false",
+ place, ty
+ );
+ false
+ }
+ ty::Slice(..) | ty::Ref(..) | ty::RawPtr(..) => {
+ debug!(
+ "place_contents_drop_state_cannot_differ place: {:?} ty: {:?} refd => true",
+ place, ty
+ );
+ true
+ }
+ _ => false,
+ }
}
fn on_all_children_bits<'tcx, F>(
/// FIXME #4948: Reuse ribs to avoid allocation.
ribs: PerNS<Vec<Rib<'a>>>,
+ /// Previous poped `rib`, only used for diagnostic.
+ last_block_rib: Option<Rib<'a>>,
+
/// The current set of local scopes, for labels.
label_ribs: Vec<Rib<'a, NodeId>>,
// Ignore errors in function bodies if this is rustdoc
// Be sure not to set this until the function signature has been resolved.
let previous_state = replace(&mut this.in_func_body, true);
+ // We only care block in the same function
+ this.last_block_rib = None;
// Resolve the function body, potentially inside the body of an async closure
this.with_lifetime_rib(
LifetimeRibKind::Elided(LifetimeRes::Infer),
type_ns: vec![Rib::new(start_rib_kind)],
macro_ns: vec![Rib::new(start_rib_kind)],
},
+ last_block_rib: None,
label_ribs: Vec::new(),
lifetime_ribs: Vec::new(),
lifetime_elision_candidates: None,
self.ribs[ValueNS].pop();
self.label_ribs.pop();
}
- self.ribs[ValueNS].pop();
+ self.last_block_rib = self.ribs[ValueNS].pop();
if anonymous_module.is_some() {
self.ribs[TypeNS].pop();
}
return (true, candidates);
}
}
+
+ // Try to find in last block rib
+ if let Some(rib) = &self.last_block_rib && let RibKind::NormalRibKind = rib.kind {
+ for (ident, &res) in &rib.bindings {
+ if let Res::Local(_) = res && path.len() == 1 &&
+ ident.span.eq_ctxt(path[0].ident.span) &&
+ ident.name == path[0].ident.name {
+ err.span_help(
+ ident.span,
+ &format!("the binding `{}` is available in a different scope in the same function", path_str),
+ );
+ return (true, candidates);
+ }
+ }
+ }
+
return (false, candidates);
}
// NOTE: We are iterating over the mapping entries from last to first
// because entries specified later on the command line should
// take precedence.
- for &(ref from, ref to) in mapping.iter().rev() {
+ for (from, to) in mapping.iter().rev() {
debug!("Trying to apply {from:?} => {to:?}");
if let Ok(rest) = path.strip_prefix(from) {
--- /dev/null
+use crate::infer::InferCtxt;
+
+use rustc_middle::ty::error::TypeError;
+use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
+use rustc_middle::ty::{self, Ty, TyCtxt};
+
+pub struct CollectAllMismatches<'a, 'tcx> {
+ pub infcx: &'a InferCtxt<'tcx>,
+ pub param_env: ty::ParamEnv<'tcx>,
+ pub errors: Vec<TypeError<'tcx>>,
+}
+
+impl<'a, 'tcx> TypeRelation<'tcx> for CollectAllMismatches<'a, 'tcx> {
+ fn tag(&self) -> &'static str {
+ "CollectAllMismatches"
+ }
+ fn tcx(&self) -> TyCtxt<'tcx> {
+ self.infcx.tcx
+ }
+ fn intercrate(&self) -> bool {
+ false
+ }
+ fn param_env(&self) -> ty::ParamEnv<'tcx> {
+ self.param_env
+ }
+ fn a_is_expected(&self) -> bool {
+ true
+ } // irrelevant
+ fn mark_ambiguous(&mut self) {
+ bug!()
+ }
+ fn relate_with_variance<T: Relate<'tcx>>(
+ &mut self,
+ _: ty::Variance,
+ _: ty::VarianceDiagInfo<'tcx>,
+ a: T,
+ b: T,
+ ) -> RelateResult<'tcx, T> {
+ self.relate(a, b)
+ }
+ fn regions(
+ &mut self,
+ a: ty::Region<'tcx>,
+ _b: ty::Region<'tcx>,
+ ) -> RelateResult<'tcx, ty::Region<'tcx>> {
+ Ok(a)
+ }
+ fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
+ if a == b || matches!(a.kind(), ty::Infer(_)) || matches!(b.kind(), ty::Infer(_)) {
+ return Ok(a);
+ }
+ relate::super_relate_tys(self, a, b).or_else(|e| {
+ self.errors.push(e);
+ Ok(a)
+ })
+ }
+ fn consts(
+ &mut self,
+ a: ty::Const<'tcx>,
+ b: ty::Const<'tcx>,
+ ) -> RelateResult<'tcx, ty::Const<'tcx>> {
+ if a == b {
+ return Ok(a);
+ }
+ relate::super_relate_consts(self, a, b) // could do something similar here for constants!
+ }
+ fn binders<T: Relate<'tcx>>(
+ &mut self,
+ a: ty::Binder<'tcx, T>,
+ b: ty::Binder<'tcx, T>,
+ ) -> RelateResult<'tcx, ty::Binder<'tcx, T>> {
+ Ok(a.rebind(self.relate(a.skip_binder(), b.skip_binder())?))
+ }
+}
mod ambiguity;
+pub mod method_chain;
pub mod on_unimplemented;
pub mod suggestions;
|err| {
self.note_obligation_cause_code(
err,
- &predicate,
+ predicate,
obligation.param_env,
obligation.cause.code(),
&mut vec![],
{
self.note_obligation_cause_code(
&mut diag,
- &error.obligation.predicate,
+ error.obligation.predicate,
error.obligation.param_env,
code,
&mut vec![],
if !self.maybe_note_obligation_cause_for_async_await(err, obligation) {
self.note_obligation_cause_code(
err,
- &obligation.predicate,
+ obligation.predicate,
obligation.param_env,
obligation.cause.code(),
&mut vec![],
+// ignore-tidy-filelength
use super::{DefIdOrName, Obligation, ObligationCause, ObligationCauseCode, PredicateObligation};
use crate::autoderef::Autoderef;
use crate::infer::InferCtxt;
-use crate::traits::NormalizeExt;
+use crate::traits::{NormalizeExt, ObligationCtxt};
use hir::def::CtorOf;
use hir::HirId;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::{InferOk, LateBoundRegionConversionTime};
use rustc_middle::hir::map;
+use rustc_middle::ty::error::TypeError::{self, Sorts};
+use rustc_middle::ty::relate::TypeRelation;
use rustc_middle::ty::{
self, suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind, DefIdTree,
- GeneratorDiagnosticData, GeneratorInteriorTypeCause, Infer, InferTy, IsSuggestable,
- ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable,
+ GeneratorDiagnosticData, GeneratorInteriorTypeCause, Infer, InferTy, InternalSubsts,
+ IsSuggestable, ToPredicate, Ty, TyCtxt, TypeAndMut, TypeFoldable, TypeFolder,
+ TypeSuperFoldable, TypeVisitable, TypeckResults,
};
-use rustc_middle::ty::{TypeAndMut, TypeckResults};
use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::{BytePos, DesugaringKind, ExpnKind, Span, DUMMY_SP};
use rustc_target::spec::abi;
-use std::fmt;
+use std::ops::Deref;
+use super::method_chain::CollectAllMismatches;
use super::InferCtxtPrivExt;
use crate::infer::InferCtxtExt as _;
use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
fn note_obligation_cause_code<T>(
&self,
err: &mut Diagnostic,
- predicate: &T,
+ predicate: T,
param_env: ty::ParamEnv<'tcx>,
cause_code: &ObligationCauseCode<'tcx>,
obligated_types: &mut Vec<Ty<'tcx>>,
seen_requirements: &mut FxHashSet<DefId>,
) where
- T: fmt::Display + ToPredicate<'tcx>;
+ T: ToPredicate<'tcx>;
/// Suggest to await before try: future? => future.await?
fn suggest_await_before_try(
err: &mut Diagnostic,
trait_pred: ty::PolyTraitPredicate<'tcx>,
);
+ fn function_argument_obligation(
+ &self,
+ arg_hir_id: HirId,
+ err: &mut Diagnostic,
+ parent_code: &ObligationCauseCode<'tcx>,
+ param_env: ty::ParamEnv<'tcx>,
+ predicate: ty::Predicate<'tcx>,
+ call_hir_id: HirId,
+ );
+ fn point_at_chain(
+ &self,
+ expr: &hir::Expr<'_>,
+ typeck_results: &TypeckResults<'tcx>,
+ type_diffs: Vec<TypeError<'tcx>>,
+ param_env: ty::ParamEnv<'tcx>,
+ err: &mut Diagnostic,
+ );
}
fn predicate_constraint(generics: &hir::Generics<'_>, pred: ty::Predicate<'_>) -> (Span, String) {
debug!(?next_code);
self.note_obligation_cause_code(
err,
- &obligation.predicate,
+ obligation.predicate,
obligation.param_env,
next_code.unwrap(),
&mut Vec::new(),
fn note_obligation_cause_code<T>(
&self,
err: &mut Diagnostic,
- predicate: &T,
+ predicate: T,
param_env: ty::ParamEnv<'tcx>,
cause_code: &ObligationCauseCode<'tcx>,
obligated_types: &mut Vec<Ty<'tcx>>,
seen_requirements: &mut FxHashSet<DefId>,
) where
- T: fmt::Display + ToPredicate<'tcx>,
+ T: ToPredicate<'tcx>,
{
let tcx = self.tcx;
+ let predicate = predicate.to_predicate(tcx);
match *cause_code {
ObligationCauseCode::ExprAssignable
| ObligationCauseCode::MatchExpressionArm { .. }
err.note("only the last element of a tuple may have a dynamically sized type");
}
ObligationCauseCode::ProjectionWf(data) => {
- err.note(&format!("required so that the projection `{}` is well-formed", data,));
+ err.note(&format!("required so that the projection `{data}` is well-formed"));
}
ObligationCauseCode::ReferenceOutlivesReferent(ref_ty) => {
err.note(&format!(
- "required so that reference `{}` does not outlive its referent",
- ref_ty,
+ "required so that reference `{ref_ty}` does not outlive its referent"
));
}
ObligationCauseCode::ObjectTypeBound(object_ty, region) => {
ensure_sufficient_stack(|| {
self.note_obligation_cause_code(
err,
- &parent_predicate,
+ parent_predicate,
param_env,
&data.parent_code,
obligated_types,
ensure_sufficient_stack(|| {
self.note_obligation_cause_code(
err,
- &parent_predicate,
+ parent_predicate,
param_env,
cause_code.peel_derives(),
obligated_types,
ensure_sufficient_stack(|| {
self.note_obligation_cause_code(
err,
- &parent_predicate,
+ parent_predicate,
param_env,
&data.parent_code,
obligated_types,
ensure_sufficient_stack(|| {
self.note_obligation_cause_code(
err,
- &parent_predicate,
+ parent_predicate,
param_env,
&data.parent_code,
obligated_types,
call_hir_id,
ref parent_code,
} => {
- let hir = self.tcx.hir();
- if let Some(Node::Expr(expr @ hir::Expr { kind: hir::ExprKind::Block(..), .. })) =
- hir.find(arg_hir_id)
- {
- let parent_id = hir.get_parent_item(arg_hir_id);
- let typeck_results: &TypeckResults<'tcx> = match &self.typeck_results {
- Some(t) if t.hir_owner == parent_id => t,
- _ => self.tcx.typeck(parent_id.def_id),
- };
- let expr = expr.peel_blocks();
- let ty = typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(tcx.ty_error());
- let span = expr.span;
- if Some(span) != err.span.primary_span() {
- err.span_label(
- span,
- if ty.references_error() {
- String::new()
- } else {
- format!("this tail expression is of type `{:?}`", ty)
- },
- );
- }
- }
- if let Some(Node::Expr(hir::Expr {
- kind:
- hir::ExprKind::Call(hir::Expr { span, .. }, _)
- | hir::ExprKind::MethodCall(
- hir::PathSegment { ident: Ident { span, .. }, .. },
- ..,
- ),
- ..
- })) = hir.find(call_hir_id)
- {
- if Some(*span) != err.span.primary_span() {
- err.span_label(*span, "required by a bound introduced by this call");
- }
- }
+ self.function_argument_obligation(
+ arg_hir_id,
+ err,
+ parent_code,
+ param_env,
+ predicate,
+ call_hir_id,
+ );
ensure_sufficient_stack(|| {
self.note_obligation_cause_code(
err,
ObligationCauseCode::CompareImplItemObligation { trait_item_def_id, kind, .. } => {
let item_name = self.tcx.item_name(trait_item_def_id);
let msg = format!(
- "the requirement `{}` appears on the `impl`'s {kind} `{}` but not on the \
- corresponding trait's {kind}",
- predicate, item_name,
+ "the requirement `{predicate}` appears on the `impl`'s {kind} \
+ `{item_name}` but not on the corresponding trait's {kind}",
);
let sp = self
.tcx
let mut assoc_span: MultiSpan = sp.into();
assoc_span.push_span_label(
sp,
- format!("this trait's {kind} doesn't have the requirement `{}`", predicate),
+ format!("this trait's {kind} doesn't have the requirement `{predicate}`"),
);
if let Some(ident) = self
.tcx
}
ObligationCauseCode::OpaqueReturnType(expr_info) => {
if let Some((expr_ty, expr_span)) = expr_info {
- let expr_ty = self.resolve_vars_if_possible(expr_ty);
+ let expr_ty = with_forced_trimmed_paths!(self.ty_to_string(expr_ty));
err.span_label(
expr_span,
format!("return type was inferred to be `{expr_ty}` here"),
);
}
}
+ fn function_argument_obligation(
+ &self,
+ arg_hir_id: HirId,
+ err: &mut Diagnostic,
+ parent_code: &ObligationCauseCode<'tcx>,
+ param_env: ty::ParamEnv<'tcx>,
+ predicate: ty::Predicate<'tcx>,
+ call_hir_id: HirId,
+ ) {
+ let tcx = self.tcx;
+ let hir = tcx.hir();
+ if let Some(Node::Expr(expr)) = hir.find(arg_hir_id) {
+ let parent_id = hir.get_parent_item(arg_hir_id);
+ let typeck_results: &TypeckResults<'tcx> = match &self.typeck_results {
+ Some(t) if t.hir_owner == parent_id => t,
+ _ => self.tcx.typeck(parent_id.def_id),
+ };
+ if let hir::Expr { kind: hir::ExprKind::Block(..), .. } = expr {
+ let expr = expr.peel_blocks();
+ let ty = typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(tcx.ty_error());
+ let span = expr.span;
+ if Some(span) != err.span.primary_span() {
+ err.span_label(
+ span,
+ if ty.references_error() {
+ String::new()
+ } else {
+ let ty = with_forced_trimmed_paths!(self.ty_to_string(ty));
+ format!("this tail expression is of type `{ty}`")
+ },
+ );
+ }
+ }
+
+ // FIXME: visit the ty to see if there's any closure involved, and if there is,
+ // check whether its evaluated return type is the same as the one corresponding
+ // to an associated type (as seen from `trait_pred`) in the predicate. Like in
+ // trait_pred `S: Sum<<Self as Iterator>::Item>` and predicate `i32: Sum<&()>`
+ let mut type_diffs = vec![];
+
+ if let ObligationCauseCode::ExprBindingObligation(def_id, _, _, idx) = parent_code.deref()
+ && let predicates = self.tcx.predicates_of(def_id).instantiate_identity(self.tcx)
+ && let Some(pred) = predicates.predicates.get(*idx)
+ && let Ok(trait_pred) = pred.kind().try_map_bound(|pred| match pred {
+ ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred)) => Ok(trait_pred),
+ _ => Err(()),
+ })
+ {
+ let mut c = CollectAllMismatches {
+ infcx: self.infcx,
+ param_env,
+ errors: vec![],
+ };
+ if let Ok(trait_predicate) = predicate.kind().try_map_bound(|pred| match pred {
+ ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred)) => Ok(trait_pred),
+ _ => Err(()),
+ }) {
+ if let Ok(_) = c.relate(trait_pred, trait_predicate) {
+ type_diffs = c.errors;
+ }
+ }
+ }
+ if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
+ && let hir::Path { res: hir::def::Res::Local(hir_id), .. } = path
+ && let Some(hir::Node::Pat(binding)) = self.tcx.hir().find(*hir_id)
+ && let parent_hir_id = self.tcx.hir().get_parent_node(binding.hir_id)
+ && let Some(hir::Node::Local(local)) = self.tcx.hir().find(parent_hir_id)
+ && let Some(binding_expr) = local.init
+ {
+ // If the expression we're calling on is a binding, we want to point at the
+ // `let` when talking about the type. Otherwise we'll point at every part
+ // of the method chain with the type.
+ self.point_at_chain(binding_expr, typeck_results, type_diffs, param_env, err);
+ } else {
+ self.point_at_chain(expr, typeck_results, type_diffs, param_env, err);
+ }
+ }
+ let call_node = hir.find(call_hir_id);
+ if let Some(Node::Expr(hir::Expr {
+ kind: hir::ExprKind::MethodCall(path, rcvr, ..), ..
+ })) = call_node
+ {
+ if Some(rcvr.span) == err.span.primary_span() {
+ err.replace_span_with(path.ident.span);
+ }
+ }
+ if let Some(Node::Expr(hir::Expr {
+ kind:
+ hir::ExprKind::Call(hir::Expr { span, .. }, _)
+ | hir::ExprKind::MethodCall(hir::PathSegment { ident: Ident { span, .. }, .. }, ..),
+ ..
+ })) = hir.find(call_hir_id)
+ {
+ if Some(*span) != err.span.primary_span() {
+ err.span_label(*span, "required by a bound introduced by this call");
+ }
+ }
+ }
+
+ fn point_at_chain(
+ &self,
+ expr: &hir::Expr<'_>,
+ typeck_results: &TypeckResults<'tcx>,
+ type_diffs: Vec<TypeError<'tcx>>,
+ param_env: ty::ParamEnv<'tcx>,
+ err: &mut Diagnostic,
+ ) {
+ let mut primary_spans = vec![];
+ let mut span_labels = vec![];
+
+ let tcx = self.tcx;
+
+ let mut assocs = vec![];
+ // We still want to point at the different methods even if there hasn't
+ // been a change of assoc type.
+ let mut call_spans = vec![];
+ let mut expr = expr;
+ let mut prev_ty = self.resolve_vars_if_possible(
+ typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(tcx.ty_error()),
+ );
+ while let hir::ExprKind::MethodCall(_path_segment, rcvr_expr, _args, span) = expr.kind {
+ // Point at every method call in the chain with the resulting type.
+ // vec![1, 2, 3].iter().map(mapper).sum<i32>()
+ // ^^^^^^ ^^^^^^^^^^^
+ expr = rcvr_expr;
+ let mut assocs_in_this_method = Vec::with_capacity(type_diffs.len());
+ call_spans.push(span);
+
+ let ocx = ObligationCtxt::new_in_snapshot(self.infcx);
+ for diff in &type_diffs {
+ let Sorts(expected_found) = diff else { continue; };
+ let ty::Projection(proj) = expected_found.expected.kind() else { continue; };
+
+ let origin =
+ TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span };
+ let trait_def_id = proj.trait_def_id(self.tcx);
+ // Make `Self` be equivalent to the type of the call chain
+ // expression we're looking at now, so that we can tell what
+ // for example `Iterator::Item` is at this point in the chain.
+ let substs = InternalSubsts::for_item(self.tcx, trait_def_id, |param, _| {
+ match param.kind {
+ ty::GenericParamDefKind::Type { .. } => {
+ if param.index == 0 {
+ return prev_ty.into();
+ }
+ }
+ ty::GenericParamDefKind::Lifetime
+ | ty::GenericParamDefKind::Const { .. } => {}
+ }
+ self.var_for_def(span, param)
+ });
+ // This will hold the resolved type of the associated type, if the
+ // current expression implements the trait that associated type is
+ // in. For example, this would be what `Iterator::Item` is here.
+ let ty_var = self.infcx.next_ty_var(origin);
+ // This corresponds to `<ExprTy as Iterator>::Item = _`.
+ let trait_ref = ty::Binder::dummy(ty::PredicateKind::Clause(
+ ty::Clause::Projection(ty::ProjectionPredicate {
+ projection_ty: ty::ProjectionTy { substs, item_def_id: proj.item_def_id },
+ term: ty_var.into(),
+ }),
+ ));
+ // Add `<ExprTy as Iterator>::Item = _` obligation.
+ ocx.register_obligation(Obligation::misc(
+ self.tcx,
+ span,
+ expr.hir_id,
+ param_env,
+ trait_ref,
+ ));
+ if ocx.select_where_possible().is_empty() {
+ // `ty_var` now holds the type that `Item` is for `ExprTy`.
+ let ty_var = self.resolve_vars_if_possible(ty_var);
+ assocs_in_this_method.push(Some((span, (proj.item_def_id, ty_var))));
+ } else {
+ // `<ExprTy as Iterator>` didn't select, so likely we've
+ // reached the end of the iterator chain, like the originating
+ // `Vec<_>`.
+ // Keep the space consistent for later zipping.
+ assocs_in_this_method.push(None);
+ }
+ }
+ assocs.push(assocs_in_this_method);
+ prev_ty = self.resolve_vars_if_possible(
+ typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(tcx.ty_error()),
+ );
+
+ if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
+ && let hir::Path { res: hir::def::Res::Local(hir_id), .. } = path
+ && let Some(hir::Node::Pat(binding)) = self.tcx.hir().find(*hir_id)
+ && let parent_hir_id = self.tcx.hir().get_parent_node(binding.hir_id)
+ && let Some(hir::Node::Local(local)) = self.tcx.hir().find(parent_hir_id)
+ && let Some(binding_expr) = local.init
+ {
+ // We've reached the root of the method call chain and it is a
+ // binding. Get the binding creation and try to continue the chain.
+ expr = binding_expr;
+ }
+ }
+ // We want the type before deref coercions, otherwise we talk about `&[_]`
+ // instead of `Vec<_>`.
+ if let Some(ty) = typeck_results.expr_ty_opt(expr) {
+ let ty = with_forced_trimmed_paths!(self.ty_to_string(ty));
+ // Point at the root expression
+ // vec![1, 2, 3].iter().map(mapper).sum<i32>()
+ // ^^^^^^^^^^^^^
+ span_labels.push((expr.span, format!("this expression has type `{ty}`")));
+ };
+ // Only show this if it is not a "trivial" expression (not a method
+ // chain) and there are associated types to talk about.
+ let mut assocs = assocs.into_iter().peekable();
+ while let Some(assocs_in_method) = assocs.next() {
+ let Some(prev_assoc_in_method) = assocs.peek() else {
+ for entry in assocs_in_method {
+ let Some((span, (assoc, ty))) = entry else { continue; };
+ if type_diffs.iter().any(|diff| {
+ let Sorts(expected_found) = diff else { return false; };
+ self.can_eq(param_env, expected_found.found, ty).is_ok()
+ }) {
+ // FIXME: this doesn't quite work for `Iterator::collect`
+ // because we have `Vec<i32>` and `()`, but we'd want `i32`
+ // to point at the `.into_iter()` call, but as long as we
+ // still point at the other method calls that might have
+ // introduced the issue, this is fine for now.
+ primary_spans.push(span);
+ }
+ span_labels.push((
+ span,
+ with_forced_trimmed_paths!(format!(
+ "`{}` is `{ty}` here",
+ self.tcx.def_path_str(assoc),
+ )),
+ ));
+ }
+ break;
+ };
+ for (entry, prev_entry) in
+ assocs_in_method.into_iter().zip(prev_assoc_in_method.into_iter())
+ {
+ match (entry, prev_entry) {
+ (Some((span, (assoc, ty))), Some((_, (_, prev_ty)))) => {
+ let ty_str = with_forced_trimmed_paths!(self.ty_to_string(ty));
+
+ let assoc = with_forced_trimmed_paths!(self.tcx.def_path_str(assoc));
+ if ty != *prev_ty {
+ if type_diffs.iter().any(|diff| {
+ let Sorts(expected_found) = diff else { return false; };
+ self.can_eq(param_env, expected_found.found, ty).is_ok()
+ }) {
+ primary_spans.push(span);
+ }
+ span_labels
+ .push((span, format!("`{assoc}` changed to `{ty_str}` here")));
+ } else {
+ span_labels.push((span, format!("`{assoc}` remains `{ty_str}` here")));
+ }
+ }
+ (Some((span, (assoc, ty))), None) => {
+ span_labels.push((
+ span,
+ with_forced_trimmed_paths!(format!(
+ "`{}` is `{}` here",
+ self.tcx.def_path_str(assoc),
+ self.ty_to_string(ty),
+ )),
+ ));
+ }
+ (None, Some(_)) | (None, None) => {}
+ }
+ }
+ }
+ for span in call_spans {
+ if span_labels.iter().find(|(s, _)| *s == span).is_none() {
+ // Ensure we are showing the entire chain, even if the assoc types
+ // haven't changed.
+ span_labels.push((span, String::new()));
+ }
+ }
+ if !primary_spans.is_empty() {
+ let mut multi_span: MultiSpan = primary_spans.into();
+ for (span, label) in span_labels {
+ multi_span.push_span_label(span, label);
+ }
+ err.span_note(
+ multi_span,
+ format!(
+ "the method call chain might not have had the expected \
+ associated types",
+ ),
+ );
+ }
+ }
}
/// Collect all the returned expressions within the input expression.
let result = if let Some(trait_def_id) = tcx.trait_of_item(def.did) {
debug!(" => associated item, attempting to find impl in param_env {:#?}", param_env);
- resolve_associated_item(tcx, def.did, param_env, trait_def_id, substs)
+ resolve_associated_item(
+ tcx,
+ def.did,
+ param_env,
+ trait_def_id,
+ tcx.normalize_erasing_regions(param_env, substs),
+ )
} else {
let ty = tcx.type_of(def.def_id_for_type_of());
let item_type = tcx.subst_and_normalize_erasing_regions(substs, param_env, ty);
unsafe { Pin::new_unchecked(&mut self.get_unchecked_mut().inner) }
}
- /// Build a _mutable_ references to an `Exclusive<T>` from
+ /// Build a _mutable_ reference to an `Exclusive<T>` from
/// a _mutable_ reference to a `T`. This allows you to skip
/// building an `Exclusive` with [`Exclusive::new`].
#[unstable(feature = "exclusive_wrapper", issue = "98407")]
unsafe { &mut *(r as *mut T as *mut Exclusive<T>) }
}
- /// Build a _pinned mutable_ references to an `Exclusive<T>` from
+ /// Build a _pinned mutable_ reference to an `Exclusive<T>` from
/// a _pinned mutable_ reference to a `T`. This allows you to skip
/// building an `Exclusive` with [`Exclusive::new`].
#[unstable(feature = "exclusive_wrapper", issue = "98407")]
use std::ffi::OsStr;
/// Retrieve an environment variable and add it to build dependency info.
- /// Build system executing the compiler will know that the variable was accessed during
+ /// The build system executing the compiler will know that the variable was accessed during
/// compilation, and will be able to rerun the build when the value of that variable changes.
/// Besides the dependency tracking this function should be equivalent to `env::var` from the
/// standard library, except that the argument must be UTF-8.
let xform = |p: &Path| {
let mut contents = t!(fs::read_to_string(p));
- for tool in &["rust-demangler"] {
+ for tool in &["rust-demangler", "miri"] {
if !built_tools.contains(tool) {
contents = filter(&contents, tool);
}
prepare("rust-std");
prepare("rust-analysis");
prepare("clippy");
- prepare("miri");
prepare("rust-analyzer");
- for tool in &["rust-docs", "rust-demangler"] {
+ for tool in &["rust-docs", "rust-demangler", "miri"] {
if built_tools.contains(tool) {
prepare(tool);
}
prepare("rust-docs");
prepare("rust-std");
prepare("clippy");
- prepare("miri");
prepare("rust-analyzer");
- for tool in &["rust-demangler"] {
+ for tool in &["rust-demangler", "miri"] {
if built_tools.contains(tool) {
prepare(tool);
}
.arg(etc.join("msi/remove-duplicates.xsl")),
);
}
- builder.run(
- Command::new(&heat)
- .current_dir(&exe)
- .arg("dir")
- .arg("miri")
- .args(&heat_flags)
- .arg("-cg")
- .arg("MiriGroup")
- .arg("-dr")
- .arg("Miri")
- .arg("-var")
- .arg("var.MiriDir")
- .arg("-out")
- .arg(exe.join("MiriGroup.wxs"))
- .arg("-t")
- .arg(etc.join("msi/remove-duplicates.xsl")),
- );
+ if built_tools.contains("miri") {
+ builder.run(
+ Command::new(&heat)
+ .current_dir(&exe)
+ .arg("dir")
+ .arg("miri")
+ .args(&heat_flags)
+ .arg("-cg")
+ .arg("MiriGroup")
+ .arg("-dr")
+ .arg("Miri")
+ .arg("-var")
+ .arg("var.MiriDir")
+ .arg("-out")
+ .arg(exe.join("MiriGroup.wxs"))
+ .arg("-t")
+ .arg(etc.join("msi/remove-duplicates.xsl")),
+ );
+ }
builder.run(
Command::new(&heat)
.current_dir(&exe)
.arg("-dStdDir=rust-std")
.arg("-dAnalysisDir=rust-analysis")
.arg("-dClippyDir=clippy")
- .arg("-dMiriDir=miri")
.arg("-arch")
.arg(&arch)
.arg("-out")
if built_tools.contains("rust-analyzer") {
cmd.arg("-dRustAnalyzerDir=rust-analyzer");
}
+ if built_tools.contains("miri") {
+ cmd.arg("-dMiriDir=miri");
+ }
if target.ends_with("windows-gnu") {
cmd.arg("-dGccDir=rust-mingw");
}
candle("CargoGroup.wxs".as_ref());
candle("StdGroup.wxs".as_ref());
candle("ClippyGroup.wxs".as_ref());
- candle("MiriGroup.wxs".as_ref());
+ if built_tools.contains("miri") {
+ candle("MiriGroup.wxs".as_ref());
+ }
if built_tools.contains("rust-demangler") {
candle("RustDemanglerGroup.wxs".as_ref());
}
.arg("StdGroup.wixobj")
.arg("AnalysisGroup.wixobj")
.arg("ClippyGroup.wixobj")
- .arg("MiriGroup.wixobj")
.current_dir(&exe);
+ if built_tools.contains("miri") {
+ cmd.arg("MiriGroup.wixobj");
+ }
if built_tools.contains("rust-analyzer") {
cmd.arg("RustAnalyzerGroup.wixobj");
}
ItemType::TraitAlias => "traitalias",
}
}
+ pub(crate) fn is_method(&self) -> bool {
+ matches!(*self, ItemType::Method | ItemType::TyMethod)
+ }
}
impl fmt::Display for ItemType {
You need to enable Javascript be able to update your settings.\
</section>\
</noscript>\
- <link rel=\"stylesheet\" type=\"text/css\" \
+ <link rel=\"stylesheet\" \
href=\"{static_root_path}{settings_css}\">\
<script defer src=\"{static_root_path}{settings_js}\"></script>",
static_root_path = page.get_static_root_path(),
let toggled = !doc_buffer.is_empty();
if toggled {
- let method_toggle_class =
- if item_type == ItemType::Method { " method-toggle" } else { "" };
+ let method_toggle_class = if item_type.is_method() { " method-toggle" } else { "" };
write!(w, "<details class=\"rustdoc-toggle{}\" open><summary>", method_toggle_class);
}
match &*item.kind {
document(&mut content, cx, m, Some(t), HeadingOffset::H5);
let toggled = !content.is_empty();
if toggled {
- write!(w, "<details class=\"rustdoc-toggle method-toggle\" open><summary>");
+ let method_toggle_class = if item_type.is_method() { " method-toggle" } else { "" };
+ write!(w, "<details class=\"rustdoc-toggle{method_toggle_class}\" open><summary>");
}
write!(w, "<section id=\"{}\" class=\"method has-srclink\">", id);
render_rightside(w, cx, m, t, RenderMode::Normal);
}
.source .content pre.rust {
- overflow: auto;
padding-left: 0;
}
function loadCss(cssUrl) {
const link = document.createElement("link");
link.href = cssUrl;
- link.type = "text/css";
link.rel = "stylesheet";
document.getElementsByTagName("head")[0].appendChild(link);
}
let mut css = String::new();
for name in &options.markdown_css {
- write!(css, r#"<link rel="stylesheet" type="text/css" href="{name}">"#)
+ write!(css, r#"<link rel="stylesheet" href="{name}">"#)
.expect("Writing to a String can't fail");
}
click: "input#line-numbers"
wait-for: 100 // wait-for-false does not exist
assert-false: "pre.example-line-numbers"
+assert-local-storage: {"rustdoc-line-numbers": "false" }
// Finally, turn it on again.
click: "input#line-numbers"
wait-for: "pre.example-line-numbers"
+assert-local-storage: {"rustdoc-line-numbers": "true" }
// summary. Trait methods with no documentation should not be wrapped.
//
// @has foo/trait.Foo.html
+// @has - '//details[@class="rustdoc-toggle"]//summary//h4[@class="code-header"]' 'type Item'
+// @!has - '//details[@class="rustdoc-toggle"]//summary//h4[@class="code-header"]' 'type Item2'
// @has - '//details[@class="rustdoc-toggle method-toggle"]//summary//h4[@class="code-header"]' 'is_documented()'
// @!has - '//details[@class="rustdoc-toggle method-toggle"]//summary//h4[@class="code-header"]' 'not_documented()'
// @has - '//details[@class="rustdoc-toggle method-toggle"]//*[@class="docblock"]' 'is_documented is documented'
// @!has - '//details[@class="rustdoc-toggle method-toggle"]//summary//h4[@class="code-header"]' 'not_documented_optional()'
// @has - '//details[@class="rustdoc-toggle method-toggle"]//*[@class="docblock"]' 'is_documented_optional is documented'
pub trait Foo {
+ /// is documented
+ type Item;
+
+ type Item2;
+
fn not_documented();
/// is_documented is documented
--- /dev/null
+// check-pass
+// compile-flags: -C debug_assertions=yes -Zunstable-options
+
+#[allow(dead_code)]
+fn problematic_function<Space>()
+where
+ DefaultAlloc: FinAllok<R1, Space>,
+{
+ let e = Edge2dElement;
+ let _ = Into::<Point>::into(e.map_reference_coords());
+}
+impl<N> Allocator<N, R0> for DefaultAlloc {
+ type Buffer = MStorage;
+}
+impl<N> Allocator<N, R1> for DefaultAlloc {
+ type Buffer = MStorage;
+}
+impl<N, D> From<VectorN<N, D>> for Point
+where
+ DefaultAlloc: Allocator<N, D>,
+{
+ fn from(_: VectorN<N, D>) -> Self {
+ unimplemented!()
+ }
+}
+impl<GeometryDim, NodalDim> FinAllok<GeometryDim, NodalDim> for DefaultAlloc
+where
+ DefaultAlloc: Allocator<Ure, GeometryDim>,
+ DefaultAlloc: Allocator<Ure, NodalDim>
+{
+}
+impl FiniteElement<R1> for Edge2dElement {
+ fn map_reference_coords(&self) -> VectorN<Ure, R1> {
+ unimplemented!()
+ }
+}
+type VectorN<N, R> = (N, R, <DefaultAlloc as Allocator<N, R>>::Buffer);
+struct DefaultAlloc;
+struct R0;
+struct R1;
+struct MStorage;
+struct Point;
+struct Edge2dElement;
+struct Ure;
+trait Allocator<N, R> {
+ type Buffer;
+}
+trait FinAllok<GeometryDim, NodalDim>:
+ Allocator<Ure, GeometryDim> +
+ Allocator<Ure, NodalDim> +
+{
+}
+trait FiniteElement<Rau>
+where
+ DefaultAlloc: FinAllok<Rau, Rau>,
+{
+ fn map_reference_coords(&self) -> VectorN<Ure, Rau>;
+}
+fn main() {}
LL | |
LL | | |x| println!("doubling {}", x);
LL | | Some(x * 2)
- | | ----------- this tail expression is of type `std::option::Option<_>`
+ | | ----------- this tail expression is of type `Option<_>`
LL | |
LL | | });
| |_____^ expected an `FnOnce<({integer},)>` closure, found `Option<_>`
error[E0277]: the trait bound `for<'a> &'a mut (): Foo<&'a mut ()>` is not satisfied
- --> $DIR/issue-101020.rs:31:5
+ --> $DIR/issue-101020.rs:31:22
|
LL | (&mut EmptyIter).consume(());
- | ^^^^^^^^^^^^^^^^ ------- required by a bound introduced by this call
- | |
- | the trait `for<'a> Foo<&'a mut ()>` is not implemented for `&'a mut ()`
+ | ^^^^^^^ the trait `for<'a> Foo<&'a mut ()>` is not implemented for `&'a mut ()`
|
note: required for `&'a mut ()` to implement `for<'a> FuncInput<'a, &'a mut ()>`
--> $DIR/issue-101020.rs:27:20
--- /dev/null
+// normalize-stderr-test: "long-type-\d+" -> "long-type-hash"
+
+fn id(
+ f: &dyn Fn(u32),
+) -> &dyn Fn(
+ &dyn Fn(
+ &dyn Fn(
+ &dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(u32))))))))),
+ ),
+ ),
+) {
+ f
+ //~^ ERROR mismatched types
+}
+
+fn main() {}
--- /dev/null
+error[E0308]: mismatched types
+ --> $DIR/hang-on-deeply-nested-dyn.rs:12:5
+ |
+LL | ) -> &dyn Fn(
+ | ______-
+LL | | &dyn Fn(
+LL | | &dyn Fn(
+LL | | &dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(u32))))))))),
+LL | | ),
+LL | | ),
+LL | | ) {
+ | |_- expected `&dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn Fn(u32) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a))` because of return type
+LL | f
+ | ^ expected reference, found `u32`
+ |
+ = note: expected reference `&dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a ...) + 'a)) + 'a)) + 'a))`
+ the full type name has been written to '$TEST_BUILD_DIR/higher-rank-trait-bounds/hang-on-deeply-nested-dyn/hang-on-deeply-nested-dyn.long-type-hash.txt'
+ found reference `&dyn Fn(u32)`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
error[E0277]: the trait bound `X: Ord` is not satisfied
- --> $DIR/issue-20162.rs:5:5
+ --> $DIR/issue-20162.rs:5:7
|
LL | b.sort();
- | ^ ---- required by a bound introduced by this call
- | |
- | the trait `Ord` is not implemented for `X`
+ | ^^^^ the trait `Ord` is not implemented for `X`
|
note: required by a bound in `slice::<impl [T]>::sort`
--> $SRC_DIR/alloc/src/slice.rs:LL:COL
let mut found_e = false;
let temp: Vec<u8> = it
- //~^ ERROR to be an iterator that yields `&_`, but it yields `u8`
.take_while(|&x| {
found_e = true;
false
})
- .cloned()
+ .cloned() //~ ERROR to be an iterator that yields `&_`, but it yields `u8`
.collect(); //~ ERROR the method
}
-error[E0271]: expected `TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:8:21: 8:25]>` to be an iterator that yields `&_`, but it yields `u8`
- --> $DIR/issue-31173.rs:6:25
- |
-LL | let temp: Vec<u8> = it
- | _________________________^
-LL | |
-LL | | .take_while(|&x| {
-LL | | found_e = true;
-LL | | false
-LL | | })
- | |__________^ expected reference, found `u8`
-LL | .cloned()
- | ------ required by a bound introduced by this call
+error[E0271]: expected `TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]>` to be an iterator that yields `&_`, but it yields `u8`
+ --> $DIR/issue-31173.rs:11:10
+ |
+LL | .cloned()
+ | ^^^^^^ expected reference, found `u8`
|
= note: expected reference `&_`
found type `u8`
LL | Self: Sized + Iterator<Item = &'a T>,
| ^^^^^^^^^^^^ required by this bound in `Iterator::cloned`
-error[E0599]: the method `collect` exists for struct `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:8:21: 8:25]>>`, but its trait bounds were not satisfied
- --> $DIR/issue-31173.rs:13:10
+error[E0599]: the method `collect` exists for struct `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>`, but its trait bounds were not satisfied
+ --> $DIR/issue-31173.rs:12:10
|
LL | .collect();
- | ^^^^^^^ method cannot be called on `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:8:21: 8:25]>>` due to unsatisfied trait bounds
+ | ^^^^^^^ method cannot be called on `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>` due to unsatisfied trait bounds
|
::: $SRC_DIR/core/src/iter/adapters/take_while.rs:LL:COL
|
| -------------------- doesn't satisfy `_: Iterator`
|
= note: the following trait bounds were not satisfied:
- `<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:8:21: 8:25]> as Iterator>::Item = &_`
- which is required by `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:8:21: 8:25]>>: Iterator`
- `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:8:21: 8:25]>>: Iterator`
- which is required by `&mut Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:8:21: 8:25]>>: Iterator`
+ `<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]> as Iterator>::Item = &_`
+ which is required by `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>: Iterator`
+ `Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>: Iterator`
+ which is required by `&mut Cloned<TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:7:21: 7:25]>>: Iterator`
error: aborting due to 2 previous errors
error[E0271]: expected `std::collections::hash_map::Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)`
- --> $DIR/issue-33941.rs:6:14
+ --> $DIR/issue-33941.rs:6:36
|
LL | for _ in HashMap::new().iter().cloned() {}
- | ^^^^^^^^^^^^^^^^^^^^^ ------ required by a bound introduced by this call
- | |
- | expected reference, found tuple
+ | ^^^^^^ expected reference, found tuple
|
= note: expected reference `&_`
found tuple `(&_, &_)`
| +
error[E0277]: a value of type `Vec<(u32, _, _)>` cannot be built from an iterator over elements of type `()`
- --> $DIR/issue-34334.rs:5:33
+ --> $DIR/issue-34334.rs:5:87
|
LL | let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_receiver)| {}).collect();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------- required by a bound introduced by this call
- | |
- | value of type `Vec<(u32, _, _)>` cannot be built from `std::iter::Iterator<Item=()>`
+ | ^^^^^^^ value of type `Vec<(u32, _, _)>` cannot be built from `std::iter::Iterator<Item=()>`
|
= help: the trait `FromIterator<()>` is not implemented for `Vec<(u32, _, _)>`
= help: the trait `FromIterator<T>` is implemented for `Vec<T>`
+note: the method call chain might not have had the expected associated types
+ --> $DIR/issue-34334.rs:5:43
+ |
+LL | let sr: Vec<(u32, _, _) = vec![];
+ | ------ this expression has type `Vec<(_, _, _)>`
+...
+LL | let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_receiver)| {}).collect();
+ | ------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Iterator::Item` changed to `()` here
+ | |
+ | `Iterator::Item` is `&(_, _, _)` here
note: required by a bound in `collect`
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
error[E0277]: a value of type `Vec<f64>` cannot be built from an iterator over elements of type `&f64`
- --> $DIR/issue-66923-show-error-for-correct-call.rs:8:24
+ --> $DIR/issue-66923-show-error-for-correct-call.rs:8:39
|
LL | let x2: Vec<f64> = x1.into_iter().collect();
- | ^^^^^^^^^^^^^^ ------- required by a bound introduced by this call
- | |
- | value of type `Vec<f64>` cannot be built from `std::iter::Iterator<Item=&f64>`
+ | ^^^^^^^ value of type `Vec<f64>` cannot be built from `std::iter::Iterator<Item=&f64>`
|
= help: the trait `FromIterator<&f64>` is not implemented for `Vec<f64>`
= help: the trait `FromIterator<T>` is implemented for `Vec<T>`
+note: the method call chain might not have had the expected associated types
+ --> $DIR/issue-66923-show-error-for-correct-call.rs:8:27
+ |
+LL | let x1: &[f64] = &v;
+ | -- this expression has type `&Vec<f64>`
+LL | let x2: Vec<f64> = x1.into_iter().collect();
+ | ^^^^^^^^^^^ `Iterator::Item` is `&f64` here
note: required by a bound in `collect`
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
| ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Iterator::collect`
error[E0277]: a value of type `Vec<f64>` cannot be built from an iterator over elements of type `&f64`
- --> $DIR/issue-66923-show-error-for-correct-call.rs:12:14
+ --> $DIR/issue-66923-show-error-for-correct-call.rs:12:29
|
LL | let x3 = x1.into_iter().collect::<Vec<f64>>();
- | ^^^^^^^^^^^^^^ ------- required by a bound introduced by this call
- | |
- | value of type `Vec<f64>` cannot be built from `std::iter::Iterator<Item=&f64>`
+ | ^^^^^^^ value of type `Vec<f64>` cannot be built from `std::iter::Iterator<Item=&f64>`
|
= help: the trait `FromIterator<&f64>` is not implemented for `Vec<f64>`
= help: the trait `FromIterator<T>` is implemented for `Vec<T>`
+note: the method call chain might not have had the expected associated types
+ --> $DIR/issue-66923-show-error-for-correct-call.rs:12:17
+ |
+LL | let x1: &[f64] = &v;
+ | -- this expression has type `&Vec<f64>`
+...
+LL | let x3 = x1.into_iter().collect::<Vec<f64>>();
+ | ^^^^^^^^^^^ `Iterator::Item` is `&f64` here
note: required by a bound in `collect`
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
//~^ ERROR an array of type `[u32; 10]` cannot be built directly from an iterator
//~| NOTE try collecting into a `Vec<{integer}>`, then using `.try_into()`
//~| NOTE required by a bound in `collect`
- //~| NOTE required by a bound introduced by this call
}
error[E0277]: an array of type `[u32; 10]` cannot be built directly from an iterator
- --> $DIR/collect-into-array.rs:2:31
+ --> $DIR/collect-into-array.rs:2:39
|
LL | let whatever: [u32; 10] = (0..10).collect();
- | ^^^^^^^ ------- required by a bound introduced by this call
- | |
- | try collecting into a `Vec<{integer}>`, then using `.try_into()`
+ | ^^^^^^^ try collecting into a `Vec<{integer}>`, then using `.try_into()`
|
= help: the trait `FromIterator<{integer}>` is not implemented for `[u32; 10]`
note: required by a bound in `collect`
//~| NOTE all local variables must have a statically known size
//~| NOTE doesn't have a size known at compile-time
//~| NOTE doesn't have a size known at compile-time
- //~| NOTE required by a bound introduced by this call
process_slice(&some_generated_vec);
}
| ^ required by this bound in `Iterator::collect`
error[E0277]: a slice of type `[i32]` cannot be built since `[i32]` has no definite size
- --> $DIR/collect-into-slice.rs:6:30
+ --> $DIR/collect-into-slice.rs:6:38
|
LL | let some_generated_vec = (0..10).collect();
- | ^^^^^^^ ------- required by a bound introduced by this call
- | |
- | try explicitly collecting into a `Vec<{integer}>`
+ | ^^^^^^^ try explicitly collecting into a `Vec<{integer}>`
|
= help: the trait `FromIterator<{integer}>` is not implemented for `[i32]`
note: required by a bound in `collect`
--- /dev/null
+fn main() {
+ let scores = vec![(0, 0)]
+ .iter()
+ .map(|(a, b)| {
+ a + b;
+ });
+ println!("{}", scores.sum::<i32>()); //~ ERROR E0277
+ println!(
+ "{}",
+ vec![0, 1]
+ .iter()
+ .map(|x| x * 2)
+ .map(|x| x as f64)
+ .map(|x| x as i64)
+ .filter(|x| *x > 0)
+ .map(|x| { x + 1 })
+ .map(|x| { x; })
+ .sum::<i32>(), //~ ERROR E0277
+ );
+ println!(
+ "{}",
+ vec![0, 1]
+ .iter()
+ .map(|x| x * 2)
+ .map(|x| x as f64)
+ .filter(|x| *x > 0.0)
+ .map(|x| { x + 1.0 })
+ .sum::<i32>(), //~ ERROR E0277
+ );
+ println!("{}", vec![0, 1].iter().map(|x| { x; }).sum::<i32>()); //~ ERROR E0277
+ println!("{}", vec![(), ()].iter().sum::<i32>()); //~ ERROR E0277
+ let a = vec![0];
+ let b = a.into_iter();
+ let c = b.map(|x| x + 1);
+ let d = c.filter(|x| *x > 10 );
+ let e = d.map(|x| {
+ x + 1;
+ });
+ let f = e.filter(|_| false);
+ let g: Vec<i32> = f.collect(); //~ ERROR E0277
+}
--- /dev/null
+error[E0277]: a value of type `i32` cannot be made by summing an iterator over elements of type `()`
+ --> $DIR/invalid-iterator-chain.rs:7:27
+ |
+LL | println!("{}", scores.sum::<i32>());
+ | ^^^ value of type `i32` cannot be made by summing a `std::iter::Iterator<Item=()>`
+ |
+ = help: the trait `Sum<()>` is not implemented for `i32`
+ = help: the following other types implement trait `Sum<A>`:
+ <i32 as Sum<&'a i32>>
+ <i32 as Sum>
+note: the method call chain might not have had the expected associated types
+ --> $DIR/invalid-iterator-chain.rs:4:10
+ |
+LL | let scores = vec![(0, 0)]
+ | ------------ this expression has type `Vec<({integer}, {integer})>`
+LL | .iter()
+ | ------ `Iterator::Item` is `&({integer}, {integer})` here
+LL | .map(|(a, b)| {
+ | __________^
+LL | | a + b;
+LL | | });
+ | |__________^ `Iterator::Item` changed to `()` here
+note: required by a bound in `std::iter::Iterator::sum`
+ --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+ |
+LL | S: Sum<Self::Item>,
+ | ^^^^^^^^^^^^^^^ required by this bound in `Iterator::sum`
+
+error[E0277]: a value of type `i32` cannot be made by summing an iterator over elements of type `()`
+ --> $DIR/invalid-iterator-chain.rs:18:14
+ |
+LL | .sum::<i32>(),
+ | ^^^ value of type `i32` cannot be made by summing a `std::iter::Iterator<Item=()>`
+ |
+ = help: the trait `Sum<()>` is not implemented for `i32`
+ = help: the following other types implement trait `Sum<A>`:
+ <i32 as Sum<&'a i32>>
+ <i32 as Sum>
+note: the method call chain might not have had the expected associated types
+ --> $DIR/invalid-iterator-chain.rs:12:14
+ |
+LL | vec![0, 1]
+ | ---------- this expression has type `Vec<{integer}>`
+LL | .iter()
+ | ------ `Iterator::Item` is `&{integer}` here
+LL | .map(|x| x * 2)
+ | ^^^^^^^^^^^^^^ `Iterator::Item` changed to `{integer}` here
+LL | .map(|x| x as f64)
+ | ----------------- `Iterator::Item` changed to `f64` here
+LL | .map(|x| x as i64)
+ | ----------------- `Iterator::Item` changed to `i64` here
+LL | .filter(|x| *x > 0)
+ | ------------------ `Iterator::Item` remains `i64` here
+LL | .map(|x| { x + 1 })
+ | ------------------ `Iterator::Item` remains `i64` here
+LL | .map(|x| { x; })
+ | ^^^^^^^^^^^^^^^ `Iterator::Item` changed to `()` here
+note: required by a bound in `std::iter::Iterator::sum`
+ --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+ |
+LL | S: Sum<Self::Item>,
+ | ^^^^^^^^^^^^^^^ required by this bound in `Iterator::sum`
+
+error[E0277]: a value of type `i32` cannot be made by summing an iterator over elements of type `f64`
+ --> $DIR/invalid-iterator-chain.rs:28:14
+ |
+LL | .sum::<i32>(),
+ | ^^^ value of type `i32` cannot be made by summing a `std::iter::Iterator<Item=f64>`
+ |
+ = help: the trait `Sum<f64>` is not implemented for `i32`
+ = help: the following other types implement trait `Sum<A>`:
+ <i32 as Sum<&'a i32>>
+ <i32 as Sum>
+note: the method call chain might not have had the expected associated types
+ --> $DIR/invalid-iterator-chain.rs:24:14
+ |
+LL | vec![0, 1]
+ | ---------- this expression has type `Vec<{integer}>`
+LL | .iter()
+ | ------ `Iterator::Item` is `&{integer}` here
+LL | .map(|x| x * 2)
+ | ^^^^^^^^^^^^^^ `Iterator::Item` changed to `{integer}` here
+LL | .map(|x| x as f64)
+ | ^^^^^^^^^^^^^^^^^ `Iterator::Item` changed to `f64` here
+LL | .filter(|x| *x > 0.0)
+ | -------------------- `Iterator::Item` remains `f64` here
+LL | .map(|x| { x + 1.0 })
+ | -------------------- `Iterator::Item` remains `f64` here
+note: required by a bound in `std::iter::Iterator::sum`
+ --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+ |
+LL | S: Sum<Self::Item>,
+ | ^^^^^^^^^^^^^^^ required by this bound in `Iterator::sum`
+
+error[E0277]: a value of type `i32` cannot be made by summing an iterator over elements of type `()`
+ --> $DIR/invalid-iterator-chain.rs:30:54
+ |
+LL | println!("{}", vec![0, 1].iter().map(|x| { x; }).sum::<i32>());
+ | ^^^ value of type `i32` cannot be made by summing a `std::iter::Iterator<Item=()>`
+ |
+ = help: the trait `Sum<()>` is not implemented for `i32`
+ = help: the following other types implement trait `Sum<A>`:
+ <i32 as Sum<&'a i32>>
+ <i32 as Sum>
+note: the method call chain might not have had the expected associated types
+ --> $DIR/invalid-iterator-chain.rs:30:38
+ |
+LL | println!("{}", vec![0, 1].iter().map(|x| { x; }).sum::<i32>());
+ | ---------- ------ ^^^^^^^^^^^^^^^ `Iterator::Item` changed to `()` here
+ | | |
+ | | `Iterator::Item` is `&{integer}` here
+ | this expression has type `Vec<{integer}>`
+note: required by a bound in `std::iter::Iterator::sum`
+ --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+ |
+LL | S: Sum<Self::Item>,
+ | ^^^^^^^^^^^^^^^ required by this bound in `Iterator::sum`
+
+error[E0277]: a value of type `i32` cannot be made by summing an iterator over elements of type `&()`
+ --> $DIR/invalid-iterator-chain.rs:31:40
+ |
+LL | println!("{}", vec![(), ()].iter().sum::<i32>());
+ | ^^^ value of type `i32` cannot be made by summing a `std::iter::Iterator<Item=&()>`
+ |
+ = help: the trait `Sum<&()>` is not implemented for `i32`
+ = help: the following other types implement trait `Sum<A>`:
+ <i32 as Sum<&'a i32>>
+ <i32 as Sum>
+note: the method call chain might not have had the expected associated types
+ --> $DIR/invalid-iterator-chain.rs:31:33
+ |
+LL | println!("{}", vec![(), ()].iter().sum::<i32>());
+ | ------------ ^^^^^^ `Iterator::Item` is `&()` here
+ | |
+ | this expression has type `Vec<()>`
+note: required by a bound in `std::iter::Iterator::sum`
+ --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+ |
+LL | S: Sum<Self::Item>,
+ | ^^^^^^^^^^^^^^^ required by this bound in `Iterator::sum`
+
+error[E0277]: a value of type `Vec<i32>` cannot be built from an iterator over elements of type `()`
+ --> $DIR/invalid-iterator-chain.rs:40:25
+ |
+LL | let g: Vec<i32> = f.collect();
+ | ^^^^^^^ value of type `Vec<i32>` cannot be built from `std::iter::Iterator<Item=()>`
+ |
+ = help: the trait `FromIterator<()>` is not implemented for `Vec<i32>`
+ = help: the trait `FromIterator<T>` is implemented for `Vec<T>`
+note: the method call chain might not have had the expected associated types
+ --> $DIR/invalid-iterator-chain.rs:36:15
+ |
+LL | let a = vec![0];
+ | ------- this expression has type `Vec<{integer}>`
+LL | let b = a.into_iter();
+ | ----------- `Iterator::Item` is `{integer}` here
+LL | let c = b.map(|x| x + 1);
+ | -------------- `Iterator::Item` remains `{integer}` here
+LL | let d = c.filter(|x| *x > 10 );
+ | -------------------- `Iterator::Item` remains `{integer}` here
+LL | let e = d.map(|x| {
+ | _______________^
+LL | | x + 1;
+LL | | });
+ | |______^ `Iterator::Item` changed to `()` here
+LL | let f = e.filter(|_| false);
+ | ----------------- `Iterator::Item` remains `()` here
+note: required by a bound in `collect`
+ --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+ |
+LL | fn collect<B: FromIterator<Self::Item>>(self) -> B
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Iterator::collect`
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
error[E0277]: a value of type `Bar` cannot be built from an iterator over elements of type `_`
- --> $DIR/branches.rs:19:9
+ --> $DIR/branches.rs:19:28
|
LL | std::iter::empty().collect()
- | ^^^^^^^^^^^^^^^^^^ ------- required by a bound introduced by this call
- | |
- | value of type `Bar` cannot be built from `std::iter::Iterator<Item=_>`
+ | ^^^^^^^ value of type `Bar` cannot be built from `std::iter::Iterator<Item=_>`
|
= help: the trait `FromIterator<_>` is not implemented for `Bar`
note: required by a bound in `collect`
error[E0277]: a value of type `Foo` cannot be built from an iterator over elements of type `_`
- --> $DIR/recursion4.rs:10:9
+ --> $DIR/recursion4.rs:10:28
|
LL | x = std::iter::empty().collect();
- | ^^^^^^^^^^^^^^^^^^ ------- required by a bound introduced by this call
- | |
- | value of type `Foo` cannot be built from `std::iter::Iterator<Item=_>`
+ | ^^^^^^^ value of type `Foo` cannot be built from `std::iter::Iterator<Item=_>`
|
= help: the trait `FromIterator<_>` is not implemented for `Foo`
note: required by a bound in `collect`
| ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Iterator::collect`
error[E0277]: a value of type `impl Debug` cannot be built from an iterator over elements of type `_`
- --> $DIR/recursion4.rs:19:9
+ --> $DIR/recursion4.rs:19:28
|
LL | x = std::iter::empty().collect();
- | ^^^^^^^^^^^^^^^^^^ ------- required by a bound introduced by this call
- | |
- | value of type `impl Debug` cannot be built from `std::iter::Iterator<Item=_>`
+ | ^^^^^^^ value of type `impl Debug` cannot be built from `std::iter::Iterator<Item=_>`
|
= help: the trait `FromIterator<_>` is not implemented for `impl Debug`
note: required by a bound in `collect`
error[E0277]: `Foo` doesn't implement `Debug`
- --> $DIR/method-help-unsatisfied-bound.rs:5:5
+ --> $DIR/method-help-unsatisfied-bound.rs:5:7
|
LL | a.unwrap();
- | ^ ------ required by a bound introduced by this call
- | |
- | `Foo` cannot be formatted using `{:?}`
+ | ^^^^^^ `Foo` cannot be formatted using `{:?}`
|
= help: the trait `Debug` is not implemented for `Foo`
= note: add `#[derive(Debug)]` to `Foo` or manually `impl Debug for Foo`
| --- ^^^^^^^^
| | |
| | the trait `T` is not implemented for `()`
- | | this tail expression is of type `_`
+ | | this tail expression is of type `()`
| required by a bound introduced by this call
|
note: required by a bound in `foo`
error[E0277]: the trait bound `S: Clone` is not satisfied in `[closure@$DIR/not-clone-closure.rs:7:17: 7:24]`
- --> $DIR/not-clone-closure.rs:11:17
+ --> $DIR/not-clone-closure.rs:11:23
|
LL | let hello = move || {
| ------- within this `[closure@$DIR/not-clone-closure.rs:7:17: 7:24]`
...
LL | let hello = hello.clone();
- | ^^^^^ ----- required by a bound introduced by this call
- | |
- | within `[closure@$DIR/not-clone-closure.rs:7:17: 7:24]`, the trait `Clone` is not implemented for `S`
+ | ^^^^^ within `[closure@$DIR/not-clone-closure.rs:7:17: 7:24]`, the trait `Clone` is not implemented for `S`
|
note: required because it's used within this closure
--> $DIR/not-clone-closure.rs:7:17
error[E0277]: a value of type `i32` cannot be made by summing an iterator over elements of type `&()`
- --> $DIR/sum.rs:4:5
+ --> $DIR/sum.rs:4:25
|
LL | vec![(), ()].iter().sum::<i32>();
- | ^^^^^^^^^^^^^^^^^^^ --- required by a bound introduced by this call
- | |
- | value of type `i32` cannot be made by summing a `std::iter::Iterator<Item=&()>`
+ | ^^^ value of type `i32` cannot be made by summing a `std::iter::Iterator<Item=&()>`
|
= help: the trait `Sum<&()>` is not implemented for `i32`
= help: the following other types implement trait `Sum<A>`:
<i32 as Sum<&'a i32>>
<i32 as Sum>
+note: the method call chain might not have had the expected associated types
+ --> $DIR/sum.rs:4:18
+ |
+LL | vec![(), ()].iter().sum::<i32>();
+ | ------------ ^^^^^^ `Iterator::Item` is `&()` here
+ | |
+ | this expression has type `Vec<()>`
note: required by a bound in `std::iter::Iterator::sum`
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
| ^^^^^^^^^^^^^^^ required by this bound in `Iterator::sum`
error[E0277]: a value of type `i32` cannot be made by multiplying all elements of type `&()` from an iterator
- --> $DIR/sum.rs:7:5
+ --> $DIR/sum.rs:7:25
|
LL | vec![(), ()].iter().product::<i32>();
- | ^^^^^^^^^^^^^^^^^^^ ------- required by a bound introduced by this call
- | |
- | value of type `i32` cannot be made by multiplying all elements from a `std::iter::Iterator<Item=&()>`
+ | ^^^^^^^ value of type `i32` cannot be made by multiplying all elements from a `std::iter::Iterator<Item=&()>`
|
= help: the trait `Product<&()>` is not implemented for `i32`
= help: the following other types implement trait `Product<A>`:
<i32 as Product<&'a i32>>
<i32 as Product>
+note: the method call chain might not have had the expected associated types
+ --> $DIR/sum.rs:7:18
+ |
+LL | vec![(), ()].iter().product::<i32>();
+ | ------------ ^^^^^^ `Iterator::Item` is `&()` here
+ | |
+ | this expression has type `Vec<()>`
note: required by a bound in `std::iter::Iterator::product`
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
--- /dev/null
+fn main() {
+ let foo = 1;
+ {
+ let bar = 2;
+ let test_func = |x| x > 3;
+ }
+ if bar == 2 { //~ ERROR cannot find value
+ println!("yes");
+ }
+ test_func(1); //~ ERROR cannot find function
+}
--- /dev/null
+error[E0425]: cannot find value `bar` in this scope
+ --> $DIR/issue-104700-inner_scope.rs:7:8
+ |
+LL | if bar == 2 {
+ | ^^^
+ |
+help: the binding `bar` is available in a different scope in the same function
+ --> $DIR/issue-104700-inner_scope.rs:4:13
+ |
+LL | let bar = 2;
+ | ^^^
+
+error[E0425]: cannot find function `test_func` in this scope
+ --> $DIR/issue-104700-inner_scope.rs:10:5
+ |
+LL | test_func(1);
+ | ^^^^^^^^^ not found in this scope
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0425`.
error[E0277]: the trait bound `NonConstImpl: ~const ConstDefaultFn` is not satisfied
- --> $DIR/const-default-method-bodies.rs:24:5
+ --> $DIR/const-default-method-bodies.rs:24:18
|
LL | NonConstImpl.a();
- | ^^^^^^^^^^^^ - required by a bound introduced by this call
- | |
- | the trait `~const ConstDefaultFn` is not implemented for `NonConstImpl`
+ | ^ the trait `~const ConstDefaultFn` is not implemented for `NonConstImpl`
|
note: the trait `ConstDefaultFn` is implemented for `NonConstImpl`, but that implementation is not `const`
--> $DIR/const-default-method-bodies.rs:24:5
error[E0277]: the trait bound `cross_crate::NonConst: ~const cross_crate::MyTrait` is not satisfied
- --> $DIR/cross-crate.rs:17:5
+ --> $DIR/cross-crate.rs:17:14
|
LL | NonConst.func();
- | ^^^^^^^^ ---- required by a bound introduced by this call
- | |
- | the trait `~const cross_crate::MyTrait` is not implemented for `cross_crate::NonConst`
+ | ^^^^ the trait `~const cross_crate::MyTrait` is not implemented for `cross_crate::NonConst`
|
note: the trait `cross_crate::MyTrait` is implemented for `cross_crate::NonConst`, but that implementation is not `const`
--> $DIR/cross-crate.rs:17:5
error[E0277]: the trait bound `cross_crate::NonConst: cross_crate::MyTrait` is not satisfied
- --> $DIR/cross-crate.rs:17:5
+ --> $DIR/cross-crate.rs:17:14
|
LL | NonConst.func();
- | ^^^^^^^^ ---- required by a bound introduced by this call
- | |
- | the trait `~const cross_crate::MyTrait` is not implemented for `cross_crate::NonConst`
+ | ^^^^ the trait `~const cross_crate::MyTrait` is not implemented for `cross_crate::NonConst`
|
note: the trait `cross_crate::MyTrait` is implemented for `cross_crate::NonConst`, but that implementation is not `const`
--> $DIR/cross-crate.rs:17:5
error[E0277]: the trait bound `(): ~const Tr` is not satisfied
- --> $DIR/default-method-body-is-const-same-trait-ck.rs:8:9
+ --> $DIR/default-method-body-is-const-same-trait-ck.rs:8:12
|
LL | ().a()
- | ^^ - required by a bound introduced by this call
- | |
- | the trait `~const Tr` is not implemented for `()`
+ | ^ the trait `~const Tr` is not implemented for `()`
|
note: the trait `Tr` is implemented for `()`, but that implementation is not `const`
--> $DIR/default-method-body-is-const-same-trait-ck.rs:8:9
error[E0277]: the trait bound `T: ~const Foo` is not satisfied
- --> $DIR/super-traits-fail-2.rs:15:5
+ --> $DIR/super-traits-fail-2.rs:15:7
|
LL | x.a();
- | ^ - required by a bound introduced by this call
- | |
- | the trait `~const Foo` is not implemented for `T`
+ | ^ the trait `~const Foo` is not implemented for `T`
|
note: the trait `Foo` is implemented for `T`, but that implementation is not `const`
--> $DIR/super-traits-fail-2.rs:15:5
error[E0277]: the trait bound `T: ~const Foo` is not satisfied
- --> $DIR/super-traits-fail-2.rs:15:5
+ --> $DIR/super-traits-fail-2.rs:15:7
|
LL | x.a();
- | ^ - required by a bound introduced by this call
- | |
- | the trait `~const Foo` is not implemented for `T`
+ | ^ the trait `~const Foo` is not implemented for `T`
|
note: the trait `Foo` is implemented for `T`, but that implementation is not `const`
--> $DIR/super-traits-fail-2.rs:15:5
error[E0277]: the trait bound `&[i8]: From<&[u8]>` is not satisfied
- --> $DIR/issue-71394-no-from-impl.rs:3:20
+ --> $DIR/issue-71394-no-from-impl.rs:3:25
|
LL | let _: &[i8] = data.into();
- | ^^^^ ---- required by a bound introduced by this call
- | |
- | the trait `From<&[u8]>` is not implemented for `&[i8]`
+ | ^^^^ the trait `From<&[u8]>` is not implemented for `&[i8]`
|
= help: the following other types implement trait `From<T>`:
<[T; LANES] as From<Simd<T, LANES>>>
error[E0277]: the trait bound `String: From<impl ToString>` is not satisfied
- --> $DIR/issue-97576.rs:8:18
+ --> $DIR/issue-97576.rs:8:22
|
LL | bar: bar.into(),
- | ^^^ ---- required by a bound introduced by this call
- | |
- | the trait `From<impl ToString>` is not implemented for `String`
+ | ^^^^ the trait `From<impl ToString>` is not implemented for `String`
|
= note: required for `impl ToString` to implement `Into<String>`
error[E0277]: the trait bound `dyn Foo: CastTo<[i32]>` is not satisfied
- --> $DIR/issue-71659.rs:30:13
+ --> $DIR/issue-71659.rs:30:15
|
LL | let x = x.cast::<[i32]>();
- | ^ ---- required by a bound introduced by this call
- | |
- | the trait `CastTo<[i32]>` is not implemented for `dyn Foo`
+ | ^^^^ the trait `CastTo<[i32]>` is not implemented for `dyn Foo`
|
note: required by a bound in `Cast::cast`
--> $DIR/issue-71659.rs:19:15