mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-19 02:13:57 +00:00
Auto merge of #110636 - matthiaskrgr:rollup-faa33c6, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #110365 (ship tools with sysroot) - #110555 (Substitute missing trait items suggestion correctly) - #110578 (fix(error): normalize whitespace during msg_to_buffer) - #110597 (remove unused ftl messages) - #110611 (Add regression test for #46506) - #110618 (Track if EvalCtxt has been tainted, make sure it can't be used to make query responses after) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
b92a41c676
@ -1336,6 +1336,7 @@ impl EmitterWriter {
|
||||
// see?
|
||||
for (text, style) in msg.iter() {
|
||||
let text = self.translate_message(text, args).map_err(Report::new).unwrap();
|
||||
let text = &normalize_whitespace(&text);
|
||||
let lines = text.split('\n').collect::<Vec<_>>();
|
||||
if lines.len() > 1 {
|
||||
for (i, line) in lines.iter().enumerate() {
|
||||
|
@ -863,7 +863,7 @@ fn check_impl_items_against_trait<'tcx>(
|
||||
if !missing_items.is_empty() {
|
||||
let full_impl_span =
|
||||
tcx.hir().span_with_body(tcx.hir().local_def_id_to_hir_id(impl_id));
|
||||
missing_items_err(tcx, tcx.def_span(impl_id), &missing_items, full_impl_span);
|
||||
missing_items_err(tcx, impl_id, &missing_items, full_impl_span);
|
||||
}
|
||||
|
||||
if let Some(missing_items) = must_implement_one_of {
|
||||
|
@ -198,7 +198,7 @@ fn report_forbidden_specialization(tcx: TyCtxt<'_>, impl_item: DefId, parent_imp
|
||||
|
||||
fn missing_items_err(
|
||||
tcx: TyCtxt<'_>,
|
||||
impl_span: Span,
|
||||
impl_def_id: LocalDefId,
|
||||
missing_items: &[ty::AssocItem],
|
||||
full_impl_span: Span,
|
||||
) {
|
||||
@ -211,6 +211,7 @@ fn missing_items_err(
|
||||
.collect::<Vec<_>>()
|
||||
.join("`, `");
|
||||
|
||||
let impl_span = tcx.def_span(impl_def_id);
|
||||
let mut err = struct_span_err!(
|
||||
tcx.sess,
|
||||
impl_span,
|
||||
@ -229,7 +230,11 @@ fn missing_items_err(
|
||||
tcx.sess.source_map().indentation_before(sugg_sp).unwrap_or_else(|| String::new());
|
||||
|
||||
for &trait_item in missing_items {
|
||||
let snippet = suggestion_signature(trait_item, tcx);
|
||||
let snippet = suggestion_signature(
|
||||
tcx,
|
||||
trait_item,
|
||||
tcx.impl_trait_ref(impl_def_id).unwrap().subst_identity(),
|
||||
);
|
||||
let code = format!("{}{}\n{}", padding, snippet, padding);
|
||||
let msg = format!("implement the missing item: `{snippet}`");
|
||||
let appl = Applicability::HasPlaceholders;
|
||||
@ -301,11 +306,11 @@ fn default_body_is_unstable(
|
||||
/// Re-sugar `ty::GenericPredicates` in a way suitable to be used in structured suggestions.
|
||||
fn bounds_from_generic_predicates<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
predicates: ty::GenericPredicates<'tcx>,
|
||||
predicates: impl IntoIterator<Item = (ty::Predicate<'tcx>, Span)>,
|
||||
) -> (String, String) {
|
||||
let mut types: FxHashMap<Ty<'tcx>, Vec<DefId>> = FxHashMap::default();
|
||||
let mut projections = vec![];
|
||||
for (predicate, _) in predicates.predicates {
|
||||
for (predicate, _) in predicates {
|
||||
debug!("predicate {:?}", predicate);
|
||||
let bound_predicate = predicate.kind();
|
||||
match bound_predicate.skip_binder() {
|
||||
@ -367,7 +372,7 @@ fn fn_sig_suggestion<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
sig: ty::FnSig<'tcx>,
|
||||
ident: Ident,
|
||||
predicates: ty::GenericPredicates<'tcx>,
|
||||
predicates: impl IntoIterator<Item = (ty::Predicate<'tcx>, Span)>,
|
||||
assoc: ty::AssocItem,
|
||||
) -> String {
|
||||
let args = sig
|
||||
@ -436,7 +441,17 @@ pub fn ty_kind_suggestion(ty: Ty<'_>) -> Option<&'static str> {
|
||||
/// Return placeholder code for the given associated item.
|
||||
/// Similar to `ty::AssocItem::suggestion`, but appropriate for use as the code snippet of a
|
||||
/// structured suggestion.
|
||||
fn suggestion_signature(assoc: ty::AssocItem, tcx: TyCtxt<'_>) -> String {
|
||||
fn suggestion_signature<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
assoc: ty::AssocItem,
|
||||
impl_trait_ref: ty::TraitRef<'tcx>,
|
||||
) -> String {
|
||||
let substs = ty::InternalSubsts::identity_for_item(tcx, assoc.def_id).rebase_onto(
|
||||
tcx,
|
||||
assoc.container_id(tcx),
|
||||
impl_trait_ref.with_self_ty(tcx, tcx.types.self_param).substs,
|
||||
);
|
||||
|
||||
match assoc.kind {
|
||||
ty::AssocKind::Fn => {
|
||||
// We skip the binder here because the binder would deanonymize all
|
||||
@ -445,16 +460,22 @@ fn suggestion_signature(assoc: ty::AssocItem, tcx: TyCtxt<'_>) -> String {
|
||||
// regions just fine, showing `fn(&MyType)`.
|
||||
fn_sig_suggestion(
|
||||
tcx,
|
||||
tcx.fn_sig(assoc.def_id).subst_identity().skip_binder(),
|
||||
tcx.fn_sig(assoc.def_id).subst(tcx, substs).skip_binder(),
|
||||
assoc.ident(tcx),
|
||||
tcx.predicates_of(assoc.def_id),
|
||||
tcx.predicates_of(assoc.def_id).instantiate_own(tcx, substs),
|
||||
assoc,
|
||||
)
|
||||
}
|
||||
ty::AssocKind::Type => format!("type {} = Type;", assoc.name),
|
||||
ty::AssocKind::Type => {
|
||||
let (generics, where_clauses) = bounds_from_generic_predicates(
|
||||
tcx,
|
||||
tcx.predicates_of(assoc.def_id).instantiate_own(tcx, substs),
|
||||
);
|
||||
format!("type {}{generics} = /* Type */{where_clauses};", assoc.name)
|
||||
}
|
||||
ty::AssocKind::Const => {
|
||||
let ty = tcx.type_of(assoc.def_id).subst_identity();
|
||||
let val = ty_kind_suggestion(ty).unwrap_or("value");
|
||||
let val = ty_kind_suggestion(ty).unwrap_or("todo!()");
|
||||
format!("const {}: {} = {};", assoc.name, ty, val)
|
||||
}
|
||||
}
|
||||
|
@ -3,21 +3,6 @@ hir_typeck_field_multiply_specified_in_initializer =
|
||||
.label = used more than once
|
||||
.previous_use_label = first use of `{$ident}`
|
||||
|
||||
hir_typeck_copy_impl_on_type_with_dtor =
|
||||
the trait `Copy` cannot be implemented for this type; the type has a destructor
|
||||
.label = `Copy` not allowed on types with destructors
|
||||
|
||||
hir_typeck_multiple_relaxed_default_bounds =
|
||||
type parameter has more than one relaxed default bound, only one is supported
|
||||
|
||||
hir_typeck_copy_impl_on_non_adt =
|
||||
the trait `Copy` cannot be implemented for this type
|
||||
.label = type is not a structure or enumeration
|
||||
|
||||
hir_typeck_trait_object_declared_with_no_traits =
|
||||
at least one trait is required for an object type
|
||||
.alias_span = this alias does not contain a trait
|
||||
|
||||
hir_typeck_functional_record_update_on_non_struct =
|
||||
functional record update syntax requires a struct
|
||||
|
||||
|
@ -57,6 +57,14 @@ pub struct EvalCtxt<'a, 'tcx> {
|
||||
pub(super) search_graph: &'a mut SearchGraph<'tcx>,
|
||||
|
||||
pub(super) nested_goals: NestedGoals<'tcx>,
|
||||
|
||||
// Has this `EvalCtxt` errored out with `NoSolution` in `try_evaluate_added_goals`?
|
||||
//
|
||||
// If so, then it can no longer be used to make a canonical query response,
|
||||
// since subsequent calls to `try_evaluate_added_goals` have possibly dropped
|
||||
// ambiguous goals. Instead, a probe needs to be introduced somewhere in the
|
||||
// evaluation code.
|
||||
tainted: Result<(), NoSolution>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
@ -121,6 +129,7 @@ impl<'tcx> InferCtxtEvalExt<'tcx> for InferCtxt<'tcx> {
|
||||
max_input_universe: ty::UniverseIndex::ROOT,
|
||||
var_values: CanonicalVarValues::dummy(),
|
||||
nested_goals: NestedGoals::new(),
|
||||
tainted: Ok(()),
|
||||
};
|
||||
let result = ecx.evaluate_goal(IsNormalizesToHack::No, goal);
|
||||
|
||||
@ -172,6 +181,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
|
||||
max_input_universe: canonical_goal.max_universe,
|
||||
search_graph,
|
||||
nested_goals: NestedGoals::new(),
|
||||
tainted: Ok(()),
|
||||
};
|
||||
ecx.compute_goal(goal)
|
||||
})
|
||||
@ -391,6 +401,10 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
|
||||
},
|
||||
);
|
||||
|
||||
if response.is_err() {
|
||||
self.tainted = Err(NoSolution);
|
||||
}
|
||||
|
||||
self.nested_goals = goals;
|
||||
response
|
||||
}
|
||||
@ -404,6 +418,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
max_input_universe: self.max_input_universe,
|
||||
search_graph: self.search_graph,
|
||||
nested_goals: self.nested_goals.clone(),
|
||||
tainted: self.tainted,
|
||||
};
|
||||
self.infcx.probe(|_| f(&mut ecx))
|
||||
}
|
||||
|
@ -51,6 +51,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
certainty: Certainty,
|
||||
) -> QueryResult<'tcx> {
|
||||
let goals_certainty = self.try_evaluate_added_goals()?;
|
||||
assert_eq!(
|
||||
self.tainted,
|
||||
Ok(()),
|
||||
"EvalCtxt is tainted -- nested goals may have been dropped in a \
|
||||
previous call to `try_evaluate_added_goals!`"
|
||||
);
|
||||
|
||||
let certainty = certainty.unify_with(goals_certainty);
|
||||
|
||||
let external_constraints = self.compute_external_query_constraints()?;
|
||||
|
@ -1328,7 +1328,6 @@ impl Step for Sysroot {
|
||||
true
|
||||
}
|
||||
});
|
||||
return INTERNER.intern_path(sysroot);
|
||||
}
|
||||
|
||||
// Symlink the source root into the same location inside the sysroot,
|
||||
|
@ -748,6 +748,7 @@ macro_rules! tool_extended {
|
||||
stable = $stable:expr
|
||||
$(,tool_std = $tool_std:literal)?
|
||||
$(,allow_features = $allow_features:expr)?
|
||||
$(,add_bins_to_sysroot = $add_bins_to_sysroot:expr)?
|
||||
;)+) => {
|
||||
$(
|
||||
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
|
||||
@ -790,7 +791,7 @@ macro_rules! tool_extended {
|
||||
|
||||
#[allow(unused_mut)]
|
||||
fn run(mut $sel, $builder: &Builder<'_>) -> Option<PathBuf> {
|
||||
$builder.ensure(ToolBuild {
|
||||
let tool = $builder.ensure(ToolBuild {
|
||||
compiler: $sel.compiler,
|
||||
target: $sel.target,
|
||||
tool: $tool_name,
|
||||
@ -800,7 +801,27 @@ macro_rules! tool_extended {
|
||||
is_optional_tool: true,
|
||||
source_type: SourceType::InTree,
|
||||
allow_features: concat!($($allow_features)*),
|
||||
})
|
||||
})?;
|
||||
|
||||
if (false $(|| !$add_bins_to_sysroot.is_empty())?) && $sel.compiler.stage > 0 {
|
||||
let bindir = $builder.sysroot($sel.compiler).join("bin");
|
||||
t!(fs::create_dir_all(&bindir));
|
||||
|
||||
#[allow(unused_variables)]
|
||||
let tools_out = $builder
|
||||
.cargo_out($sel.compiler, Mode::ToolRustc, $sel.target);
|
||||
|
||||
$(for add_bin in $add_bins_to_sysroot {
|
||||
let bin_source = tools_out.join(exe(add_bin, $sel.target));
|
||||
let bin_destination = bindir.join(exe(add_bin, $sel.compiler.host));
|
||||
$builder.copy(&bin_source, &bin_destination);
|
||||
})?
|
||||
|
||||
let tool = bindir.join(exe($tool_name, $sel.compiler.host));
|
||||
Some(tool)
|
||||
} else {
|
||||
Some(tool)
|
||||
}
|
||||
}
|
||||
}
|
||||
)+
|
||||
@ -814,15 +835,15 @@ macro_rules! tool_extended {
|
||||
tool_extended!((self, builder),
|
||||
Cargofmt, "src/tools/rustfmt", "cargo-fmt", stable=true;
|
||||
CargoClippy, "src/tools/clippy", "cargo-clippy", stable=true;
|
||||
Clippy, "src/tools/clippy", "clippy-driver", stable=true;
|
||||
Miri, "src/tools/miri", "miri", stable=false;
|
||||
CargoMiri, "src/tools/miri/cargo-miri", "cargo-miri", stable=true;
|
||||
Clippy, "src/tools/clippy", "clippy-driver", stable=true, add_bins_to_sysroot = ["clippy-driver", "cargo-clippy"];
|
||||
Miri, "src/tools/miri", "miri", stable=false, add_bins_to_sysroot = ["miri"];
|
||||
CargoMiri, "src/tools/miri/cargo-miri", "cargo-miri", stable=true, add_bins_to_sysroot = ["cargo-miri"];
|
||||
// FIXME: tool_std is not quite right, we shouldn't allow nightly features.
|
||||
// But `builder.cargo` doesn't know how to handle ToolBootstrap in stages other than 0,
|
||||
// and this is close enough for now.
|
||||
Rls, "src/tools/rls", "rls", stable=true, tool_std=true;
|
||||
RustDemangler, "src/tools/rust-demangler", "rust-demangler", stable=false, tool_std=true;
|
||||
Rustfmt, "src/tools/rustfmt", "rustfmt", stable=true;
|
||||
Rustfmt, "src/tools/rustfmt", "rustfmt", stable=true, add_bins_to_sysroot = ["rustfmt", "cargo-fmt"];
|
||||
);
|
||||
|
||||
impl<'a> Builder<'a> {
|
||||
|
24
tests/rustdoc/issue-46506-pub-reexport-of-pub-reexport.rs
Normal file
24
tests/rustdoc/issue-46506-pub-reexport-of-pub-reexport.rs
Normal file
@ -0,0 +1,24 @@
|
||||
// This is a regression test for <https://github.com/rust-lang/rust/issues/46506>.
|
||||
// This test ensures that if public re-exported is re-exported, it won't be inlined.
|
||||
|
||||
#![crate_name = "foo"]
|
||||
|
||||
// @has 'foo/associations/index.html'
|
||||
// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 1
|
||||
// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Traits'
|
||||
// @has - '//*[@id="main-content"]//a[@href="trait.GroupedBy.html"]' 'GroupedBy'
|
||||
// @has 'foo/associations/trait.GroupedBy.html'
|
||||
pub mod associations {
|
||||
mod belongs_to {
|
||||
pub trait GroupedBy {}
|
||||
}
|
||||
pub use self::belongs_to::GroupedBy;
|
||||
}
|
||||
|
||||
// @has 'foo/prelude/index.html'
|
||||
// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 1
|
||||
// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Re-exports'
|
||||
// @has - '//*[@id="main-content"]//*[@id="reexport.GroupedBy"]' 'pub use associations::GroupedBy;'
|
||||
pub mod prelude {
|
||||
pub use associations::GroupedBy;
|
||||
}
|
@ -4,8 +4,8 @@ error[E0046]: not all trait items implemented, missing: `Error`, `try_from`
|
||||
LL | impl TryFrom<OtherStream> for MyStream {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Error`, `try_from` in implementation
|
||||
|
|
||||
= help: implement the missing item: `type Error = Type;`
|
||||
= help: implement the missing item: `fn try_from(_: T) -> Result<Self, <Self as TryFrom<T>>::Error> { todo!() }`
|
||||
= help: implement the missing item: `type Error = /* Type */;`
|
||||
= help: implement the missing item: `fn try_from(_: OtherStream) -> Result<Self, <Self as TryFrom<OtherStream>>::Error> { todo!() }`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
7
tests/ui/extenv/issue-110547.rs
Normal file
7
tests/ui/extenv/issue-110547.rs
Normal file
@ -0,0 +1,7 @@
|
||||
// compile-flags: -C debug-assertions
|
||||
|
||||
fn main() {
|
||||
env!{"\t"}; //~ ERROR not defined at compile time
|
||||
env!("\t"); //~ ERROR not defined at compile time
|
||||
env!("\u{2069}"); //~ ERROR not defined at compile time
|
||||
}
|
29
tests/ui/extenv/issue-110547.stderr
Normal file
29
tests/ui/extenv/issue-110547.stderr
Normal file
@ -0,0 +1,29 @@
|
||||
error: environment variable ` ` not defined at compile time
|
||||
--> $DIR/issue-110547.rs:4:5
|
||||
|
|
||||
LL | env!{"\t"};
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= help: use `std::env::var(" ")` to read the variable at run time
|
||||
= note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: environment variable ` ` not defined at compile time
|
||||
--> $DIR/issue-110547.rs:5:5
|
||||
|
|
||||
LL | env!("\t");
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= help: use `std::env::var(" ")` to read the variable at run time
|
||||
= note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: environment variable `` not defined at compile time
|
||||
--> $DIR/issue-110547.rs:6:5
|
||||
|
|
||||
LL | env!("\u{2069}");
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: use `std::env::var("")` to read the variable at run time
|
||||
= note: this error originates in the macro `env` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
@ -0,0 +1,5 @@
|
||||
pub trait Foo {
|
||||
type Gat<T>
|
||||
where
|
||||
T: std::fmt::Display;
|
||||
}
|
11
tests/ui/generic-associated-types/missing-item-sugg.rs
Normal file
11
tests/ui/generic-associated-types/missing-item-sugg.rs
Normal file
@ -0,0 +1,11 @@
|
||||
// aux-build:missing-item-sugg.rs
|
||||
|
||||
extern crate missing_item_sugg;
|
||||
|
||||
struct Local;
|
||||
impl missing_item_sugg::Foo for Local {
|
||||
//~^ ERROR not all trait items implemented, missing: `Gat`
|
||||
}
|
||||
//~^ HELP implement the missing item: `type Gat<T> = /* Type */ where T: std::fmt::Display;`
|
||||
|
||||
fn main() {}
|
11
tests/ui/generic-associated-types/missing-item-sugg.stderr
Normal file
11
tests/ui/generic-associated-types/missing-item-sugg.stderr
Normal file
@ -0,0 +1,11 @@
|
||||
error[E0046]: not all trait items implemented, missing: `Gat`
|
||||
--> $DIR/missing-item-sugg.rs:6:1
|
||||
|
|
||||
LL | impl missing_item_sugg::Foo for Local {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Gat` in implementation
|
||||
|
|
||||
= help: implement the missing item: `type Gat<T> = /* Type */ where T: std::fmt::Display;`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0046`.
|
@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `partial_cmp`
|
||||
LL | impl PartialOrd for Thing {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ missing `partial_cmp` in implementation
|
||||
|
|
||||
= help: implement the missing item: `fn partial_cmp(&self, _: &Rhs) -> Option<std::cmp::Ordering> { todo!() }`
|
||||
= help: implement the missing item: `fn partial_cmp(&self, _: &Thing) -> Option<std::cmp::Ordering> { todo!() }`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -5,7 +5,7 @@ LL | impl m1::X for X {
|
||||
| ^^^^^^^^^^^^^^^^ missing `CONSTANT`, `Type`, `method`, `method2`, `method3`, `method4`, `method5` in implementation
|
||||
|
|
||||
= help: implement the missing item: `const CONSTANT: u32 = 42;`
|
||||
= help: implement the missing item: `type Type = Type;`
|
||||
= help: implement the missing item: `type Type = /* Type */;`
|
||||
= help: implement the missing item: `fn method(&self, _: String) -> <Self as m1::X>::Type { todo!() }`
|
||||
= help: implement the missing item: `fn method2(self: Box<Self>, _: String) -> <Self as m1::X>::Type { todo!() }`
|
||||
= help: implement the missing item: `fn method3(_: &Self, _: String) -> <Self as m1::X>::Type { todo!() }`
|
||||
|
@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `Item`
|
||||
LL | impl Iterator for Recurrence {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Item` in implementation
|
||||
|
|
||||
= help: implement the missing item: `type Item = Type;`
|
||||
= help: implement the missing item: `type Item = /* Type */;`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `Output`
|
||||
LL | impl<C: Component> FnOnce<(C,)> for Prototype {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Output` in implementation
|
||||
|
|
||||
= help: implement the missing item: `type Output = Type;`
|
||||
= help: implement the missing item: `type Output = /* Type */;`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -4,7 +4,7 @@ error[E0046]: not all trait items implemented, missing: `Target`
|
||||
LL | impl Deref for Thing {
|
||||
| ^^^^^^^^^^^^^^^^^^^^ missing `Target` in implementation
|
||||
|
|
||||
= help: implement the missing item: `type Target = Type;`
|
||||
= help: implement the missing item: `type Target = /* Type */;`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -0,0 +1,16 @@
|
||||
pub trait TraitB {
|
||||
type Item;
|
||||
}
|
||||
|
||||
pub trait TraitA<A> {
|
||||
type Type;
|
||||
|
||||
fn bar<T>(_: T) -> Self;
|
||||
|
||||
fn baz<T>(_: T) -> Self
|
||||
where
|
||||
T: TraitB,
|
||||
<T as TraitB>::Item: Copy;
|
||||
|
||||
const A: usize;
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
// run-rustfix
|
||||
trait TraitB {
|
||||
type Item;
|
||||
}
|
||||
|
||||
trait TraitA<A> {
|
||||
type Type;
|
||||
fn bar<T>(_: T) -> Self;
|
||||
fn baz<T>(_: T) -> Self where T: TraitB, <T as TraitB>::Item: Copy;
|
||||
}
|
||||
|
||||
struct S;
|
||||
struct Type;
|
||||
|
||||
impl TraitA<()> for S { //~ ERROR not all trait items implemented
|
||||
fn baz<T>(_: T) -> Self where T: TraitB, <T as TraitB>::Item: Copy { todo!() }
|
||||
fn bar<T>(_: T) -> Self { todo!() }
|
||||
type Type = Type;
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -1,18 +1,15 @@
|
||||
// run-rustfix
|
||||
trait TraitB {
|
||||
type Item;
|
||||
}
|
||||
// aux-build:missing-assoc-fn-applicable-suggestions.rs
|
||||
|
||||
trait TraitA<A> {
|
||||
type Type;
|
||||
fn bar<T>(_: T) -> Self;
|
||||
fn baz<T>(_: T) -> Self where T: TraitB, <T as TraitB>::Item: Copy;
|
||||
}
|
||||
extern crate missing_assoc_fn_applicable_suggestions;
|
||||
use missing_assoc_fn_applicable_suggestions::TraitA;
|
||||
|
||||
struct S;
|
||||
struct Type;
|
||||
|
||||
impl TraitA<()> for S { //~ ERROR not all trait items implemented
|
||||
impl TraitA<()> for S {
|
||||
//~^ ERROR not all trait items implemented
|
||||
}
|
||||
//~^ HELP implement the missing item: `type Type = /* Type */;`
|
||||
//~| HELP implement the missing item: `fn bar<T>(_: T) -> Self { todo!() }`
|
||||
//~| HELP implement the missing item: `fn baz<T>(_: T) -> Self where T: TraitB, <T as TraitB>::Item: Copy { todo!() }`
|
||||
//~| HELP implement the missing item: `const A: usize = 42;`
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,15 +1,13 @@
|
||||
error[E0046]: not all trait items implemented, missing: `Type`, `bar`, `baz`
|
||||
--> $DIR/missing-assoc-fn-applicable-suggestions.rs:15:1
|
||||
error[E0046]: not all trait items implemented, missing: `Type`, `bar`, `baz`, `A`
|
||||
--> $DIR/missing-assoc-fn-applicable-suggestions.rs:7:1
|
||||
|
|
||||
LL | type Type;
|
||||
| --------- `Type` from trait
|
||||
LL | fn bar<T>(_: T) -> Self;
|
||||
| ------------------------ `bar` from trait
|
||||
LL | fn baz<T>(_: T) -> Self where T: TraitB, <T as TraitB>::Item: Copy;
|
||||
| ------------------------------------------------------------------- `baz` from trait
|
||||
...
|
||||
LL | impl TraitA<()> for S {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ missing `Type`, `bar`, `baz` in implementation
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ missing `Type`, `bar`, `baz`, `A` in implementation
|
||||
|
|
||||
= help: implement the missing item: `type Type = /* Type */;`
|
||||
= help: implement the missing item: `fn bar<T>(_: T) -> Self { todo!() }`
|
||||
= help: implement the missing item: `fn baz<T>(_: T) -> Self where T: TraitB, <T as TraitB>::Item: Copy { todo!() }`
|
||||
= help: implement the missing item: `const A: usize = 42;`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -28,7 +28,7 @@ error[E0046]: not all trait items implemented, missing: `from_iter`
|
||||
LL | impl FromIterator<()> for X {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `from_iter` in implementation
|
||||
|
|
||||
= help: implement the missing item: `fn from_iter<T>(_: T) -> Self where T: IntoIterator, std::iter::IntoIterator::Item = A { todo!() }`
|
||||
= help: implement the missing item: `fn from_iter<T>(_: T) -> Self where T: IntoIterator, std::iter::IntoIterator::Item = () { todo!() }`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user