Auto merge of #136041 - matthiaskrgr:rollup-5r1k45x, r=matthiaskrgr

Rollup of 9 pull requests

Successful merges:

 - #135971 (Properly report error when object type param default references self)
 - #135977 (Fix `FormattingOptions` instantiation with `Default`)
 - #135985 (Rename test to `unresolvable-upvar-issue-87987.rs` and add some notes)
 - #135991 (Fix set_name in thread mod for NuttX)
 - #136009 (bootstrap: Handle bootstrap lockfile race condition better)
 - #136018 (Use short ty string for move errors)
 - #136027 (Skip suggestions in `derive`d code)
 - #136029 (Bootstrap: Don't move ownership of job object)
 - #136034 (fix(bootstrap): deserialize null as `f64::NAN`)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2025-01-25 08:56:41 +00:00
commit f94018810c
34 changed files with 274 additions and 126 deletions

View file

@ -92,6 +92,9 @@ borrowck_lifetime_constraints_error =
borrowck_limitations_implies_static =
due to current limitations in the borrow checker, this implies a `'static` lifetime
borrowck_long_type_consider_verbose = consider using `--verbose` to print the full type name to the console
borrowck_long_type_full_path = the full type name has been written to '{$path}'
borrowck_move_closure_suggestion =
consider adding 'move' keyword before the nested closure

View file

@ -289,6 +289,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
None => "value".to_owned(),
};
if needs_note {
let mut path = None;
let ty = self.infcx.tcx.short_ty_string(ty, &mut path);
if let Some(local) = place.as_local() {
let span = self.body.local_decls[local].source_info.span;
err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label {
@ -304,6 +306,11 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
place: &note_msg,
});
};
if let Some(path) = path {
err.subdiagnostic(crate::session_diagnostics::LongTypePath {
path: path.display().to_string(),
});
}
}
if let UseSpans::FnSelfUse {

View file

@ -596,12 +596,19 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
self.suggest_cloning(err, place_ty, expr, None);
}
let mut path = None;
let ty = self.infcx.tcx.short_ty_string(place_ty, &mut path);
err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label {
is_partial_move: false,
ty: place_ty,
ty,
place: &place_desc,
span,
});
if let Some(path) = path {
err.subdiagnostic(crate::session_diagnostics::LongTypePath {
path: path.display().to_string(),
});
}
} else {
binds_to.sort();
binds_to.dedup();
@ -628,12 +635,19 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
self.suggest_cloning(err, place_ty, expr, Some(use_spans));
}
let mut path = None;
let ty = self.infcx.tcx.short_ty_string(place_ty, &mut path);
err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label {
is_partial_move: false,
ty: place_ty,
ty,
place: &place_desc,
span: use_span,
});
if let Some(path) = path {
err.subdiagnostic(crate::session_diagnostics::LongTypePath {
path: path.display().to_string(),
});
}
use_spans.args_subdiag(err, |args_span| {
crate::session_diagnostics::CaptureArgLabel::MoveOutPlace {
@ -831,12 +845,19 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
self.suggest_cloning(err, bind_to.ty, expr, None);
}
let mut path = None;
let ty = self.infcx.tcx.short_ty_string(bind_to.ty, &mut path);
err.subdiagnostic(crate::session_diagnostics::TypeNoCopy::Label {
is_partial_move: false,
ty: bind_to.ty,
ty,
place: place_desc,
span: binding_span,
});
if let Some(path) = path {
err.subdiagnostic(crate::session_diagnostics::LongTypePath {
path: path.display().to_string(),
});
}
}
}

View file

@ -459,17 +459,24 @@ pub(crate) enum OnClosureNote<'a> {
}
#[derive(Subdiagnostic)]
pub(crate) enum TypeNoCopy<'a, 'tcx> {
#[note(borrowck_long_type_full_path)]
#[note(borrowck_long_type_consider_verbose)]
pub(crate) struct LongTypePath {
pub(crate) path: String,
}
#[derive(Subdiagnostic)]
pub(crate) enum TypeNoCopy<'a> {
#[label(borrowck_ty_no_impl_copy)]
Label {
is_partial_move: bool,
ty: Ty<'tcx>,
ty: String,
place: &'a str,
#[primary_span]
span: Span,
},
#[note(borrowck_ty_no_impl_copy)]
Note { is_partial_move: bool, ty: Ty<'tcx>, place: &'a str },
Note { is_partial_move: bool, ty: String, place: &'a str },
}
#[derive(Diagnostic)]

View file

@ -3,12 +3,10 @@ A type parameter which references `Self` in its default value was not specified.
Erroneous code example:
```compile_fail,E0393
trait A<T=Self> {}
trait A<T = Self> {}
fn together_we_will_rule_the_galaxy(son: &A) {}
// error: the type parameter `T` must be explicitly specified in an
// object type because its default value `Self` references the
// type `Self`
fn together_we_will_rule_the_galaxy(son: &dyn A) {}
// error: the type parameter `T` must be explicitly specified
```
A trait object is defined over a single, fully-defined trait. With a regular
@ -23,7 +21,7 @@ disallowed. Making the trait concrete by explicitly specifying the value of the
defaulted parameter will fix this issue. Fixed example:
```
trait A<T=Self> {}
trait A<T = Self> {}
fn together_we_will_rule_the_galaxy(son: &A<i32>) {} // Ok!
fn together_we_will_rule_the_galaxy(son: &dyn A<i32>) {} // Ok!
```

View file

@ -353,7 +353,13 @@ hir_analysis_missing_type_params =
[one] reference
*[other] references
} to {$parameters}
.note = because of the default `Self` reference, type parameters must be specified on object types
.note = because the parameter {$parameterCount ->
[one] default references
*[other] defaults reference
} `Self`, the {$parameterCount ->
[one] parameter
*[other] parameters
} must be specified on the object type
hir_analysis_multiple_relaxed_default_bounds =
type parameter has more than one relaxed default bound, only one is supported

View file

@ -237,16 +237,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
// Skip `Self`
.skip(1)
.map(|(index, arg)| {
if arg == dummy_self.into() {
if arg.walk().any(|arg| arg == dummy_self.into()) {
let param = &generics.own_params[index];
missing_type_params.push(param.name);
Ty::new_misc_error(tcx).into()
} else if arg.walk().any(|arg| arg == dummy_self.into()) {
let guar = self.dcx().span_delayed_bug(
span,
"trait object trait bounds reference `Self`",
);
replace_dummy_self_with_error(tcx, arg, guar)
} else {
arg
}

View file

@ -185,6 +185,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
rhs_ty: Ty<'tcx>,
can_satisfy: impl FnOnce(Ty<'tcx>, Ty<'tcx>) -> bool,
) -> bool {
if lhs_expr.span.in_derive_expansion() || rhs_expr.span.in_derive_expansion() {
return false;
}
let Some((_, lhs_output_ty, lhs_inputs)) = self.extract_callable_info(lhs_ty) else {
return false;
};

View file

@ -25,6 +25,8 @@ mir_build_borrow_of_moved_value = borrow of moved value
.occurs_because_label = move occurs because `{$name}` has type `{$ty}`, which does not implement the `Copy` trait
.value_borrowed_label = value borrowed here after move
.suggestion = borrow this binding in the pattern to avoid moving the value
.full_type_name = the full type name has been written to '{$path}'
.consider_verbose = consider using `--verbose` to print the full type name to the console
mir_build_call_to_deprecated_safe_fn_requires_unsafe =
call to deprecated safe function `{$function}` is unsafe and requires unsafe block

View file

@ -790,7 +790,7 @@ pub(crate) struct IrrefutableLetPatternsWhileLet {
#[derive(Diagnostic)]
#[diag(mir_build_borrow_of_moved_value)]
pub(crate) struct BorrowOfMovedValue<'tcx> {
pub(crate) struct BorrowOfMovedValue {
#[primary_span]
#[label]
#[label(mir_build_occurs_because_label)]
@ -798,9 +798,13 @@ pub(crate) struct BorrowOfMovedValue<'tcx> {
#[label(mir_build_value_borrowed_label)]
pub(crate) conflicts_ref: Vec<Span>,
pub(crate) name: Symbol,
pub(crate) ty: Ty<'tcx>,
pub(crate) ty: String,
#[suggestion(code = "ref ", applicability = "machine-applicable")]
pub(crate) suggest_borrowing: Option<Span>,
#[note(mir_build_full_type_name)]
#[note(mir_build_consider_verbose)]
pub(crate) has_path: bool,
pub(crate) path: String,
}
#[derive(Diagnostic)]

View file

@ -795,12 +795,16 @@ fn check_borrow_conflicts_in_at_patterns<'tcx>(cx: &MatchVisitor<'_, 'tcx>, pat:
}
});
if !conflicts_ref.is_empty() {
let mut path = None;
let ty = cx.tcx.short_ty_string(ty, &mut path);
sess.dcx().emit_err(BorrowOfMovedValue {
binding_span: pat.span,
conflicts_ref,
name,
ty,
suggest_borrowing: Some(pat.span.shrink_to_lo()),
has_path: path.is_some(),
path: path.map(|p| p.display().to_string()).unwrap_or_default(),
});
}
return;

View file

@ -288,7 +288,7 @@ pub enum DebugAsHex {
///
/// `FormattingOptions` is a [`Formatter`] without an attached [`Write`] trait.
/// It is mainly used to construct `Formatter` instances.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[unstable(feature = "formatting_options", issue = "118117")]
pub struct FormattingOptions {
flags: u32,
@ -508,6 +508,15 @@ impl FormattingOptions {
}
}
#[unstable(feature = "formatting_options", issue = "118117")]
impl Default for FormattingOptions {
/// Same as [`FormattingOptions::new()`].
fn default() -> Self {
// The `#[derive(Default)]` implementation would set `fill` to `\0` instead of space.
Self::new()
}
}
/// Configuration for formatting.
///
/// A `Formatter` represents various options related to formatting. Users do not

View file

@ -51,6 +51,12 @@ fn test_maybe_uninit_short() {
assert_eq!(format!("{x:?}"), "MaybeUninit<u32>");
}
#[test]
fn formatting_options_ctor() {
use core::fmt::FormattingOptions;
assert_eq!(FormattingOptions::new(), FormattingOptions::default());
}
#[test]
fn formatting_options_flags() {
use core::fmt::*;

View file

@ -130,7 +130,12 @@ impl Thread {
}
}
#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "dragonfly"))]
#[cfg(any(
target_os = "linux",
target_os = "freebsd",
target_os = "dragonfly",
target_os = "nuttx"
))]
pub fn set_name(name: &CStr) {
unsafe {
cfg_if::cfg_if! {
@ -139,7 +144,7 @@ impl Thread {
const TASK_COMM_LEN: usize = 16;
let name = truncate_cstr::<{ TASK_COMM_LEN }>(name);
} else {
// FreeBSD and DragonFly BSD do not enforce length limits.
// FreeBSD, DragonFly, FreeBSD and NuttX do not enforce length limits.
}
};
// Available since glibc 2.12, musl 1.1.16, and uClibc 1.0.20 for Linux,
@ -150,7 +155,7 @@ impl Thread {
}
}
#[cfg(any(target_os = "openbsd", target_os = "nuttx"))]
#[cfg(target_os = "openbsd")]
pub fn set_name(name: &CStr) {
unsafe {
libc::pthread_set_name_np(libc::pthread_self(), name.as_ptr());

View file

@ -1310,9 +1310,6 @@ def bootstrap(args):
args = [build.bootstrap_binary()]
args.extend(sys.argv[1:])
env = os.environ.copy()
# The Python process ID is used when creating a Windows job object
# (see src\bootstrap\src\utils\job.rs)
env["BOOTSTRAP_PARENT_ID"] = str(os.getpid())
env["BOOTSTRAP_PYTHON"] = sys.executable
run(args, env=env, verbose=build.verbose, is_bootstrap=True)

View file

@ -57,7 +57,9 @@ fn main() {
}
err => {
drop(err);
if let Ok(pid) = pid {
// #135972: We can reach this point when the lock has been taken,
// but the locker has not yet written its PID to the file
if let Some(pid) = pid.ok().filter(|pid| !pid.is_empty()) {
println!("WARNING: build directory locked by process {pid}, waiting for lock");
} else {
println!("WARNING: build directory locked, waiting for lock");

View file

@ -42,9 +42,9 @@ pub unsafe fn setup(build: &mut crate::Build) {
#[cfg(windows)]
mod for_windows {
use std::ffi::c_void;
use std::{env, io, mem};
use std::{io, mem};
use windows::Win32::Foundation::{CloseHandle, DUPLICATE_SAME_ACCESS, DuplicateHandle, HANDLE};
use windows::Win32::Foundation::CloseHandle;
use windows::Win32::System::Diagnostics::Debug::{
SEM_NOGPFAULTERRORBOX, SetErrorMode, THREAD_ERROR_MODE,
};
@ -53,9 +53,7 @@ mod for_windows {
JOB_OBJECT_LIMIT_PRIORITY_CLASS, JOBOBJECT_EXTENDED_LIMIT_INFORMATION,
JobObjectExtendedLimitInformation, SetInformationJobObject,
};
use windows::Win32::System::Threading::{
BELOW_NORMAL_PRIORITY_CLASS, GetCurrentProcess, OpenProcess, PROCESS_DUP_HANDLE,
};
use windows::Win32::System::Threading::{BELOW_NORMAL_PRIORITY_CLASS, GetCurrentProcess};
use windows::core::PCWSTR;
use crate::Build;
@ -95,49 +93,8 @@ mod for_windows {
return;
}
// If we've got a parent process (e.g., the python script that called us)
// then move ownership of this job object up to them. That way if the python
// script is killed (e.g., via ctrl-c) then we'll all be torn down.
//
// If we don't have a parent (e.g., this was run directly) then we
// intentionally leak the job object handle. When our process exits
// Note: we intentionally leak the job object handle. When our process exits
// (normally or abnormally) it will close the handle implicitly, causing all
// processes in the job to be cleaned up.
let pid = match env::var("BOOTSTRAP_PARENT_ID") {
Ok(s) => s,
Err(..) => return,
};
let parent = match OpenProcess(PROCESS_DUP_HANDLE, false, pid.parse().unwrap()).ok() {
Some(parent) => parent,
_ => {
// If we get a null parent pointer here, it is possible that either
// we have an invalid pid or the parent process has been closed.
// Since the first case rarely happens
// (only when wrongly setting the environmental variable),
// it might be better to improve the experience of the second case
// when users have interrupted the parent process and we haven't finish
// duplicating the handle yet.
return;
}
};
let mut parent_handle = HANDLE::default();
// If this fails, well at least we tried! An example of DuplicateHandle
// failing in the past has been when the wrong python2 package spawned this
// build system (e.g., the `python2` package in MSYS instead of
// `mingw-w64-x86_64-python2`). Not sure why it failed, but the "failure
// mode" here is that we only clean everything up when the build system
// dies, not when the python parent does, so not too bad.
let _ = DuplicateHandle(
GetCurrentProcess(),
job,
parent,
&mut parent_handle,
0,
false,
DUPLICATE_SAME_ACCESS,
);
CloseHandle(parent).ok();
}
}

View file

@ -16,6 +16,7 @@ pub struct JsonInvocation {
//
// This is necessary to easily correlate this invocation with logs or other data.
pub start_time: u64,
#[serde(deserialize_with = "null_as_f64_nan")]
pub duration_including_children_sec: f64,
pub children: Vec<JsonNode>,
}
@ -28,6 +29,7 @@ pub enum JsonNode {
type_: String,
debug_repr: String,
#[serde(deserialize_with = "null_as_f64_nan")]
duration_excluding_children_sec: f64,
system_stats: JsonStepSystemStats,
@ -88,5 +90,11 @@ pub struct JsonInvocationSystemStats {
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct JsonStepSystemStats {
#[serde(deserialize_with = "null_as_f64_nan")]
pub cpu_utilization_percent: f64,
}
fn null_as_f64_nan<'de, D: serde::Deserializer<'de>>(d: D) -> Result<f64, D::Error> {
use serde::Deserialize as _;
Option::<f64>::deserialize(d).map(|f| f.unwrap_or(f64::NAN))
}

View file

@ -409,7 +409,6 @@ ui/closure_context/issue-26046-fn-once.rs
ui/closure_context/issue-42065.rs
ui/closures/2229_closure_analysis/issue-118144.rs
ui/closures/2229_closure_analysis/issue-87378.rs
ui/closures/2229_closure_analysis/issue-87987.rs
ui/closures/2229_closure_analysis/issue-88118-2.rs
ui/closures/2229_closure_analysis/issue-88476.rs
ui/closures/2229_closure_analysis/issue-89606.rs

View file

@ -1,27 +0,0 @@
//@ run-pass
//@ edition:2021
struct Props {
field_1: u32, //~ WARNING: fields `field_1` and `field_2` are never read
field_2: u32,
}
fn main() {
// Test 1
let props_2 = Props { field_1: 1, field_2: 1 };
let _ = || {
let _: Props = props_2;
};
// Test 2
let mut arr = [1, 3, 4, 5];
let mref = &mut arr;
let _c = || match arr {
[_, _, _, _] => println!("A"),
};
println!("{:#?}", mref);
}

View file

@ -1,14 +0,0 @@
warning: fields `field_1` and `field_2` are never read
--> $DIR/issue-87987.rs:5:5
|
LL | struct Props {
| ----- fields in this struct
LL | field_1: u32,
| ^^^^^^^
LL | field_2: u32,
| ^^^^^^^
|
= note: `#[warn(dead_code)]` on by default
warning: 1 warning emitted

View file

@ -0,0 +1,46 @@
//! When a closure syntactically captures a place, but doesn't actually capture
//! it, make sure MIR building doesn't ICE when handling that place.
//!
//! Under the Rust 2021 disjoint capture rules, this sort of non-capture can
//! occur when a place is only inspected by infallible non-binding patterns.
// FIXME(#135985): On its own, this test should probably just be check-pass.
// But there are few/no other tests that use non-binding array patterns and
// invoke the later parts of the compiler, so building/running has some value.
//@ run-pass
//@ edition:2021
#[expect(dead_code)]
struct Props {
field_1: u32,
field_2: u32,
}
fn main() {
// Test 1
let props_2 = Props { field_1: 1, field_2: 1 };
let _ = || {
let _: Props = props_2;
};
// Test 2
let mut arr = [1, 3, 4, 5];
let mref = &mut arr;
// These array patterns don't need to inspect the array, so the array
// isn't captured.
let _c = || match arr {
[_, _, _, _] => println!("C"),
};
let _d = || match arr {
[_, .., _] => println!("D"),
};
let _e = || match arr {
[_, ..] => println!("E"),
};
println!("{:#?}", mref);
}

View file

@ -0,0 +1,8 @@
use std::rc::Rc;
#[derive(PartialEq)] //~ NOTE in this expansion
pub struct Function {
callback: Rc<dyn Fn()>, //~ ERROR binary operation `==` cannot be applied to type `Rc<dyn Fn()>`
}
fn main() {}

View file

@ -0,0 +1,14 @@
error[E0369]: binary operation `==` cannot be applied to type `Rc<dyn Fn()>`
--> $DIR/do-not-suggest-calling-fn-in-derive-macro.rs:5:5
|
LL | #[derive(PartialEq)]
| --------- in this derive macro expansion
LL | pub struct Function {
LL | callback: Rc<dyn Fn()>,
| ^^^^^^^^^^^^^^^^^^^^^^
|
= note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0369`.

View file

@ -0,0 +1,17 @@
//@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes
//@ normalize-stderr: "long-type-\d+" -> "long-type-hash"
type A = (String, String, String, String);
type B = (A, A, A, A);
type C = (B, B, B, B);
type D = (C, C, C, C);
trait Trait {}
fn require_trait<T: Trait>() {}
fn foo(x: D) {
let _a = x;
let _b = x; //~ ERROR use of moved value
}
fn main() {}

View file

@ -0,0 +1,20 @@
error[E0382]: use of moved value: `x`
--> $DIR/non-copy-type-moved.rs:14:14
|
LL | fn foo(x: D) {
| - move occurs because `x` has type `((..., ..., ..., ...), ..., ..., ...)`, which does not implement the `Copy` trait
LL | let _a = x;
| - value moved here
LL | let _b = x;
| ^ value used here after move
|
= note: the full type name has been written to '$TEST_BUILD_DIR/diagnostic-width/non-copy-type-moved/non-copy-type-moved.long-type-hash.txt'
= note: consider using `--verbose` to print the full type name to the console
help: consider cloning the value if the performance cost is acceptable
|
LL | let _a = x.clone();
| ++++++++
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0382`.

View file

@ -0,0 +1,17 @@
trait A<C = <Self as D>::E> {}
trait D {
type E;
}
impl A<()> for () {}
impl D for () {
type E = ();
}
fn f() {
let B: &dyn A = &();
//~^ ERROR the type parameter `C` must be explicitly specified
}
fn main() {}

View file

@ -0,0 +1,18 @@
error[E0393]: the type parameter `C` must be explicitly specified
--> $DIR/default-param-self-projection.rs:13:17
|
LL | trait A<C = <Self as D>::E> {}
| --------------------------- type parameter `C` must be specified for this
...
LL | let B: &dyn A = &();
| ^
|
= note: because the parameter default references `Self`, the parameter must be specified on the object type
help: set the type parameter to the desired type
|
LL | let B: &dyn A<C> = &();
| +++
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0393`.

View file

@ -7,7 +7,7 @@ LL |
LL | fn together_we_will_rule_the_galaxy(son: &dyn A) {}
| ^
|
= note: because of the default `Self` reference, type parameters must be specified on object types
= note: because the parameter default references `Self`, the parameter must be specified on the object type
help: set the type parameter to the desired type
|
LL | fn together_we_will_rule_the_galaxy(son: &dyn A<T>) {}

View file

@ -7,7 +7,7 @@ LL |
LL | fn f(a: &dyn A) {}
| ^
|
= note: because of the default `Self` reference, type parameters must be specified on object types
= note: because the parameter default references `Self`, the parameter must be specified on the object type
help: set the type parameter to the desired type
|
LL | fn f(a: &dyn A<T>) {}

View file

@ -10,6 +10,7 @@ fn w<'a, T: 'a, F: Fn(&'a T)>() {
let b: &dyn FromResidual = &();
//~^ ERROR: the trait `FromResidual` is not dyn compatible
//~| ERROR: the trait `FromResidual` is not dyn compatible
//~| ERROR the type parameter `R` must be explicitly specified
}
fn main() {}

View file

@ -1,3 +1,18 @@
error[E0393]: the type parameter `R` must be explicitly specified
--> $DIR/canonicalize-fresh-infer-vars-issue-103626.rs:10:17
|
LL | trait FromResidual<R = <Self as Try>::Residual> {
| ----------------------------------------------- type parameter `R` must be specified for this
...
LL | let b: &dyn FromResidual = &();
| ^^^^^^^^^^^^
|
= note: because the parameter default references `Self`, the parameter must be specified on the object type
help: set the type parameter to the desired type
|
LL | let b: &dyn FromResidual<R> = &();
| +++
error[E0038]: the trait `FromResidual` is not dyn compatible
--> $DIR/canonicalize-fresh-infer-vars-issue-103626.rs:10:32
|
@ -45,6 +60,7 @@ help: alternatively, consider constraining `from_residual` so it does not apply
LL | fn from_residual(residual: R) -> Self where Self: Sized;
| +++++++++++++++++
error: aborting due to 2 previous errors
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0038`.
Some errors have detailed explanations: E0038, E0393.
For more information about an error, try `rustc --explain E0038`.

View file

@ -97,7 +97,7 @@ LL | pub trait Bar<X=usize, A=Self> {
LL | let e = Bar::<usize>::lol();
| ^^^^^^^^^^^^ missing reference to `A`
|
= note: because of the default `Self` reference, type parameters must be specified on object types
= note: because the parameter default references `Self`, the parameter must be specified on the object type
error: aborting due to 5 previous errors; 5 warnings emitted

View file

@ -7,7 +7,7 @@ LL | trait Foo<T=Self> {
LL | fn foo(x: &dyn Foo) { }
| ^^^
|
= note: because of the default `Self` reference, type parameters must be specified on object types
= note: because the parameter default references `Self`, the parameter must be specified on the object type
help: set the type parameter to the desired type
|
LL | fn foo(x: &dyn Foo<T>) { }