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:
bors 2023-04-21 05:54:13 +00:00
commit b92a41c676
25 changed files with 210 additions and 84 deletions

View File

@ -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() {

View File

@ -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 {

View File

@ -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)
}
}

View File

@ -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

View File

@ -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))
}

View File

@ -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()?;

View File

@ -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,

View File

@ -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> {

View 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;
}

View File

@ -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

View 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
}

View 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

View File

@ -0,0 +1,5 @@
pub trait Foo {
type Gat<T>
where
T: std::fmt::Display;
}

View 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() {}

View 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`.

View File

@ -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

View File

@ -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!() }`

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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() {}

View File

@ -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() {}

View File

@ -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

View File

@ -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