Skip to content

Commit

Permalink
Auto merge of rust-lang#125203 - matthiaskrgr:rollup-5pv7drz, r=matth…
Browse files Browse the repository at this point in the history
…iaskrgr

Rollup of 5 pull requests

Successful merges:

 - rust-lang#123694 (expand: fix minor diagnostics bug)
 - rust-lang#125171 (Rename `flatten(_mut)` → `as_flattened(_mut)`)
 - rust-lang#125181 (set `rust.channel` properly in source tarballs)
 - rust-lang#125186 (Remove duplicate word from addr docs)
 - rust-lang#125191 (Report better WF obligation leaf obligations in new solver)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed May 17, 2024
2 parents 8af67ba + 3695449 commit 1189851
Show file tree
Hide file tree
Showing 25 changed files with 183 additions and 126 deletions.
5 changes: 5 additions & 0 deletions compiler/rustc_expand/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ expand_attribute_meta_item =
expand_attribute_single_word =
attribute must only be a single word
expand_attributes_on_expressions_experimental =
attributes on expressions are experimental
.help_outer_doc = `///` is used for outer documentation comments; for a plain comment, use `//`
.help_inner_doc = `//!` is used for inner documentation comments; for a plain comment, use `//` by removing the `!` or inserting a space in between them: `// !`
expand_attributes_wrong_form =
attribute must be of form: `attributes(foo, bar)`
Expand Down
9 changes: 6 additions & 3 deletions compiler/rustc_expand/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,6 @@ impl<'a> StripUnconfigured<'a> {
}

/// If attributes are not allowed on expressions, emit an error for `attr`
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
#[instrument(level = "trace", skip(self))]
pub(crate) fn maybe_emit_expr_attr_err(&self, attr: &Attribute) {
if self.features.is_some_and(|features| !features.stmt_expr_attributes)
Expand All @@ -392,11 +391,15 @@ impl<'a> StripUnconfigured<'a> {
&self.sess,
sym::stmt_expr_attributes,
attr.span,
"attributes on expressions are experimental",
crate::fluent_generated::expand_attributes_on_expressions_experimental,
);

if attr.is_doc_comment() {
err.help("`///` is for documentation comments. For a plain comment, use `//`.");
err.help(if attr.style == AttrStyle::Outer {
crate::fluent_generated::expand_help_outer_doc
} else {
crate::fluent_generated::expand_help_inner_doc
});
}

err.emit();
Expand Down
77 changes: 57 additions & 20 deletions compiler/rustc_trait_selection/src/solve/fulfill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,39 +384,64 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
return ControlFlow::Break(self.obligation.clone());
}

// FIXME: Could we extract a trait ref from a projection here too?
let tcx = goal.infcx().tcx;
// FIXME: Also, what about considering >1 layer up the stack? May be necessary
// for normalizes-to.
let Some(parent_trait_pred) = goal.goal().predicate.to_opt_poly_trait_pred() else {
return ControlFlow::Break(self.obligation.clone());
let pred_kind = goal.goal().predicate.kind();
let child_mode = match pred_kind.skip_binder() {
ty::PredicateKind::Clause(ty::ClauseKind::Trait(parent_trait_pred)) => {
ChildMode::Trait(pred_kind.rebind(parent_trait_pred))
}
ty::PredicateKind::NormalizesTo(normalizes_to)
if matches!(
normalizes_to.alias.kind(tcx),
ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst
) =>
{
ChildMode::Trait(pred_kind.rebind(ty::TraitPredicate {
trait_ref: normalizes_to.alias.trait_ref(tcx),
polarity: ty::PredicatePolarity::Positive,
}))
}
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_)) => {
ChildMode::WellFormedObligation
}
_ => {
return ControlFlow::Break(self.obligation.clone());
}
};

let tcx = goal.infcx().tcx;
let mut impl_where_bound_count = 0;
for nested_goal in candidate.instantiate_nested_goals(self.span()) {
let make_obligation = |cause| Obligation {
cause,
param_env: nested_goal.goal().param_env,
predicate: nested_goal.goal().predicate,
recursion_depth: self.obligation.recursion_depth + 1,
};

let obligation;
match nested_goal.source() {
GoalSource::Misc => {
match (child_mode, nested_goal.source()) {
(ChildMode::Trait(_), GoalSource::Misc) => {
continue;
}
GoalSource::ImplWhereBound => {
obligation = Obligation {
cause: derive_cause(
tcx,
candidate.kind(),
self.obligation.cause.clone(),
impl_where_bound_count,
parent_trait_pred,
),
param_env: nested_goal.goal().param_env,
predicate: nested_goal.goal().predicate,
recursion_depth: self.obligation.recursion_depth + 1,
};
(ChildMode::Trait(parent_trait_pred), GoalSource::ImplWhereBound) => {
obligation = make_obligation(derive_cause(
tcx,
candidate.kind(),
self.obligation.cause.clone(),
impl_where_bound_count,
parent_trait_pred,
));
impl_where_bound_count += 1;
}
GoalSource::InstantiateHigherRanked => {
// Skip over a higher-ranked predicate.
(_, GoalSource::InstantiateHigherRanked) => {
obligation = self.obligation.clone();
}
(ChildMode::WellFormedObligation, _) => {
obligation = make_obligation(self.obligation.cause.clone());
}
}

// Skip nested goals that aren't the *reason* for our goal's failure.
Expand All @@ -436,6 +461,18 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
}
}

#[derive(Copy, Clone)]
enum ChildMode<'tcx> {
// Try to derive an `ObligationCause::{ImplDerived,BuiltinDerived}`,
// and skip all `GoalSource::Misc`, which represent useless obligations
// such as alias-eq which may not hold.
Trait(ty::PolyTraitPredicate<'tcx>),
// Skip trying to derive an `ObligationCause` from this obligation, and
// report *all* sub-obligations as if they came directly from the parent
// obligation.
WellFormedObligation,
}

fn derive_cause<'tcx>(
tcx: TyCtxt<'tcx>,
candidate_kind: ProbeKind<'tcx>,
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/ptr/mut_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ impl<T: ?Sized> *mut T {
///
/// This is similar to `self as usize`, which semantically discards *provenance* and
/// *address-space* information. However, unlike `self as usize`, casting the returned address
/// back to a pointer yields yields a [pointer without provenance][without_provenance_mut], which is undefined
/// back to a pointer yields a [pointer without provenance][without_provenance_mut], which is undefined
/// behavior to dereference. To properly restore the lost information and obtain a
/// dereferenceable pointer, use [`with_addr`][pointer::with_addr] or
/// [`map_addr`][pointer::map_addr].
Expand Down
16 changes: 8 additions & 8 deletions library/core/src/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4533,21 +4533,21 @@ impl<T, const N: usize> [[T; N]] {
/// ```
/// #![feature(slice_flatten)]
///
/// assert_eq!([[1, 2, 3], [4, 5, 6]].flatten(), &[1, 2, 3, 4, 5, 6]);
/// assert_eq!([[1, 2, 3], [4, 5, 6]].as_flattened(), &[1, 2, 3, 4, 5, 6]);
///
/// assert_eq!(
/// [[1, 2, 3], [4, 5, 6]].flatten(),
/// [[1, 2], [3, 4], [5, 6]].flatten(),
/// [[1, 2, 3], [4, 5, 6]].as_flattened(),
/// [[1, 2], [3, 4], [5, 6]].as_flattened(),
/// );
///
/// let slice_of_empty_arrays: &[[i32; 0]] = &[[], [], [], [], []];
/// assert!(slice_of_empty_arrays.flatten().is_empty());
/// assert!(slice_of_empty_arrays.as_flattened().is_empty());
///
/// let empty_slice_of_arrays: &[[u32; 10]] = &[];
/// assert!(empty_slice_of_arrays.flatten().is_empty());
/// assert!(empty_slice_of_arrays.as_flattened().is_empty());
/// ```
#[unstable(feature = "slice_flatten", issue = "95629")]
pub const fn flatten(&self) -> &[T] {
pub const fn as_flattened(&self) -> &[T] {
let len = if T::IS_ZST {
self.len().checked_mul(N).expect("slice len overflow")
} else {
Expand Down Expand Up @@ -4581,11 +4581,11 @@ impl<T, const N: usize> [[T; N]] {
/// }
///
/// let mut array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
/// add_5_to_all(array.flatten_mut());
/// add_5_to_all(array.as_flattened_mut());
/// assert_eq!(array, [[6, 7, 8], [9, 10, 11], [12, 13, 14]]);
/// ```
#[unstable(feature = "slice_flatten", issue = "95629")]
pub fn flatten_mut(&mut self) -> &mut [T] {
pub fn as_flattened_mut(&mut self) -> &mut [T] {
let len = if T::IS_ZST {
self.len().checked_mul(N).expect("slice len overflow")
} else {
Expand Down
4 changes: 2 additions & 2 deletions library/core/tests/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2609,14 +2609,14 @@ fn test_slice_from_ptr_range() {
#[should_panic = "slice len overflow"]
fn test_flatten_size_overflow() {
let x = &[[(); usize::MAX]; 2][..];
let _ = x.flatten();
let _ = x.as_flattened();
}

#[test]
#[should_panic = "slice len overflow"]
fn test_flatten_mut_size_overflow() {
let x = &mut [[(); usize::MAX]; 2][..];
let _ = x.flatten_mut();
let _ = x.as_flattened_mut();
}

#[test]
Expand Down
11 changes: 9 additions & 2 deletions src/bootstrap/src/core/config/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1307,6 +1307,9 @@ impl Config {
toml_path = config.src.join(toml_path);
}

let file_content = t!(fs::read_to_string(config.src.join("src/ci/channel")));
let ci_channel = file_content.trim_end();

// Give a hard error if `--config` or `RUST_BOOTSTRAP_CONFIG` are set to a missing path,
// but not if `config.toml` hasn't been created.
let mut toml = if !using_default_path || toml_path.exists() {
Expand Down Expand Up @@ -1534,6 +1537,7 @@ impl Config {
let mut omit_git_hash = None;
let mut lld_enabled = None;

let mut is_user_configured_rust_channel = false;
if let Some(rust) = toml.rust {
let Rust {
optimize: optimize_toml,
Expand Down Expand Up @@ -1591,15 +1595,14 @@ impl Config {
lld_mode,
} = rust;

is_user_configured_rust_channel = channel.is_some();
set(&mut config.channel, channel);

config.download_rustc_commit = config.download_ci_rustc_commit(download_rustc);
// This list is incomplete, please help by expanding it!
if config.download_rustc_commit.is_some() {
// We need the channel used by the downloaded compiler to match the one we set for rustdoc;
// otherwise rustdoc-ui tests break.
let ci_channel = t!(fs::read_to_string(config.src.join("src/ci/channel")));
let ci_channel = ci_channel.trim_end();
if config.channel != ci_channel
&& !(config.channel == "dev" && ci_channel == "nightly")
{
Expand Down Expand Up @@ -1717,6 +1720,10 @@ impl Config {
config.omit_git_hash = omit_git_hash.unwrap_or(default);
config.rust_info = GitInfo::new(config.omit_git_hash, &config.src);

if config.rust_info.is_from_tarball() && !is_user_configured_rust_channel {
ci_channel.clone_into(&mut config.channel);
}

if let Some(llvm) = toml.llvm {
let Llvm {
optimize: optimize_toml,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
error: the type `Foo::Bar<Vec<[u32]>>` is not well-formed
--> $DIR/wf-check-skipped.rs:17:14
error[E0277]: the size for values of type `[u32]` cannot be known at compilation time
--> $DIR/wf-check-skipped.rs:17:25
|
LL | fn main() -> Foo::Bar::<Vec<[u32]>> {}
| ^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `[u32]`

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0277`.
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ impl Foo {
}

fn main() -> Foo::Bar::<Vec<[u32]>> {}
//[next]~^ ERROR the type `Foo::Bar<Vec<[u32]>>` is not well-formed
//[next]~^ ERROR the size for values of type `[u32]` cannot be known at compilation time
11 changes: 11 additions & 0 deletions tests/ui/feature-gates/feature-gate-stmt_expr_attributes.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
const X: i32 = #[allow(dead_code)] 8;
//~^ ERROR attributes on expressions are experimental

const Y: i32 =
/// foo
//~^ ERROR attributes on expressions are experimental
8;

const Z: i32 = {
//! foo
//~^ ERROR attributes on expressions are experimental
8
};

fn main() {}
24 changes: 23 additions & 1 deletion tests/ui/feature-gates/feature-gate-stmt_expr_attributes.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,28 @@ LL | const X: i32 = #[allow(dead_code)] 8;
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error: aborting due to 1 previous error
error[E0658]: attributes on expressions are experimental
--> $DIR/feature-gate-stmt_expr_attributes.rs:5:5
|
LL | /// foo
| ^^^^^^^
|
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
= help: `///` is used for outer documentation comments; for a plain comment, use `//`

error[E0658]: attributes on expressions are experimental
--> $DIR/feature-gate-stmt_expr_attributes.rs:10:5
|
LL | //! foo
| ^^^^^^^
|
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
= help: `//!` is used for inner documentation comments; for a plain comment, use `//` by removing the `!` or inserting a space in between them: `// !`

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0658`.
20 changes: 1 addition & 19 deletions tests/ui/for/issue-20605.next.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,13 @@ help: consider mutably borrowing here
LL | for item in &mut *things { *item = 0 }
| ++++

error: the type `<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter` is not well-formed
--> $DIR/issue-20605.rs:6:17
|
LL | for item in *things { *item = 0 }
| ^^^^^^^

error: the type `&mut <dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter` is not well-formed
--> $DIR/issue-20605.rs:6:17
|
LL | for item in *things { *item = 0 }
| ^^^^^^^

error: the type `Option<<<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter as Iterator>::Item>` is not well-formed
--> $DIR/issue-20605.rs:6:17
|
LL | for item in *things { *item = 0 }
| ^^^^^^^

error[E0614]: type `<dyn Iterator<Item = &'a mut u8> as IntoIterator>::Item` cannot be dereferenced
--> $DIR/issue-20605.rs:6:27
|
LL | for item in *things { *item = 0 }
| ^^^^^

error: aborting due to 5 previous errors
error: aborting due to 2 previous errors

Some errors have detailed explanations: E0277, E0614.
For more information about an error, try `rustc --explain E0277`.
3 changes: 0 additions & 3 deletions tests/ui/for/issue-20605.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ fn changer<'a>(mut things: Box<dyn Iterator<Item=&'a mut u8>>) {
for item in *things { *item = 0 }
//[current]~^ ERROR `dyn Iterator<Item = &'a mut u8>` is not an iterator
//[next]~^^ ERROR `dyn Iterator<Item = &'a mut u8>` is not an iterator
//[next]~| ERROR the type `<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter` is not well-formed
//[next]~| ERROR the type `&mut <dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter` is not well-formed
//[next]~| ERROR the type `Option<<<dyn Iterator<Item = &'a mut u8> as IntoIterator>::IntoIter as Iterator>::Item>` is not well-formed
//[next]~| ERROR type `<dyn Iterator<Item = &'a mut u8> as IntoIterator>::Item` cannot be dereferenced

// FIXME(-Znext-solver): these error messages are horrible and have to be
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ struct W<T>(T);
// `usize: Foo` doesn't hold. Therefore we ICE, because we don't expect to still
// encounter weak types in `assemble_alias_bound_candidates_recur`.
fn hello(_: W<A<usize>>) {}
//~^ ERROR the type `W<A<usize>>` is not well-formed
//~^ ERROR the size for values of type `A<usize>` cannot be known at compilation time

fn main() {}
7 changes: 5 additions & 2 deletions tests/ui/impl-trait/in-trait/alias-bounds-when-not-wf.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@ LL | #![feature(lazy_type_alias)]
= note: see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
= note: `#[warn(incomplete_features)]` on by default

error: the type `W<A<usize>>` is not well-formed
error[E0277]: the size for values of type `A<usize>` cannot be known at compilation time
--> $DIR/alias-bounds-when-not-wf.rs:16:13
|
LL | fn hello(_: W<A<usize>>) {}
| ^^^^^^^^^^^
| ^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `A<usize>`

error: aborting due to 1 previous error; 1 warning emitted

For more information about this error, try `rustc --explain E0277`.
2 changes: 1 addition & 1 deletion tests/ui/lint/unused/unused-doc-comments-edge-cases.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ LL | (/// useless doc comment
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
= help: `///` is for documentation comments. For a plain comment, use `//`.
= help: `///` is used for outer documentation comments; for a plain comment, use `//`

error: unused doc comment
--> $DIR/unused-doc-comments-edge-cases.rs:6:9
Expand Down
Loading

0 comments on commit 1189851

Please sign in to comment.