Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 7 pull requests #87433

Closed
wants to merge 15 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion RELEASES.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Libraries
- [`leading_zeros`, and `trailing_zeros` are now available on all
`NonZero` integer types.][84082]
- [`{f32, f64}::from_str` now parse and print special values
(`NaN`, `-0`) according to IEEE RFC 754.][78618]
(`NaN`, `-0`) according to IEEE 754.][78618]
- [You can now index into slices using `(Bound<usize>, Bound<usize>)`.][77704]
- [Add the `BITS` associated constant to all numeric types.][82565]

Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_expand/src/base.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::expand::{self, AstFragment, Invocation};
use crate::module::DirOwnership;

use rustc_ast::attr::MarkedAttrs;
use rustc_ast::ptr::P;
use rustc_ast::token::{self, Nonterminal};
use rustc_ast::tokenstream::{CanSynthesizeMissingTokens, TokenStream};
Expand Down Expand Up @@ -951,6 +952,10 @@ pub struct ExtCtxt<'a> {
///
/// `Ident` is the module name.
pub(super) extern_mod_loaded: OnExternModLoaded<'a>,
/// When we 'expand' an inert attribute, we leave it
/// in the AST, but insert it here so that we know
/// not to expand it again.
pub(super) expanded_inert_attrs: MarkedAttrs,
}

impl<'a> ExtCtxt<'a> {
Expand All @@ -977,6 +982,7 @@ impl<'a> ExtCtxt<'a> {
},
force_mode: false,
expansions: FxHashMap::default(),
expanded_inert_attrs: MarkedAttrs::new(),
}
}

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_expand/src/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -754,7 +754,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
}
}
SyntaxExtensionKind::NonMacroAttr { mark_used } => {
self.cx.sess.mark_attr_known(&attr);
self.cx.expanded_inert_attrs.mark(&attr);
if *mark_used {
self.cx.sess.mark_attr_used(&attr);
}
Expand Down Expand Up @@ -1040,7 +1040,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
item.visit_attrs(|attrs| {
attr = attrs
.iter()
.position(|a| !self.cx.sess.is_attr_known(a) && !is_builtin_attr(a))
.position(|a| !self.cx.expanded_inert_attrs.is_marked(a) && !is_builtin_attr(a))
.map(|attr_pos| {
let attr = attrs.remove(attr_pos);
let following_derives = attrs[attr_pos..]
Expand Down
7 changes: 5 additions & 2 deletions compiler/rustc_metadata/src/locator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1080,7 +1080,10 @@ impl CrateError {
locator.triple
));
}
if missing_core && std::env::var("RUSTUP_HOME").is_ok() {
// NOTE: this suggests using rustup, even though the user may not have it installed.
// That's because they could choose to install it; or this may give them a hint which
// target they need to install from their distro.
if missing_core {
err.help(&format!(
"consider downloading the target with `rustup target add {}`",
locator.triple
Expand All @@ -1097,7 +1100,7 @@ impl CrateError {
current_crate
));
}
if sess.is_nightly_build() && std::env::var("CARGO").is_ok() {
if sess.is_nightly_build() {
err.help("consider building the standard library from source with `cargo build -Zbuild-std`");
}
} else if Some(crate_name)
Expand Down
65 changes: 45 additions & 20 deletions compiler/rustc_middle/src/ty/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,7 @@ impl<T> Trait<T> for X {
assoc_substs,
ty,
msg,
false,
) {
return true;
}
Expand All @@ -646,6 +647,7 @@ impl<T> Trait<T> for X {
assoc_substs,
ty,
msg,
false,
);
}
}
Expand Down Expand Up @@ -771,13 +773,24 @@ fn foo(&self) -> Self::T { String::new() }
) -> bool {
let assoc = self.associated_item(proj_ty.item_def_id);
if let ty::Opaque(def_id, _) = *proj_ty.self_ty().kind() {
self.constrain_associated_type_structured_suggestion(
let opaque_local_def_id = def_id.expect_local();
let opaque_hir_id = self.hir().local_def_id_to_hir_id(opaque_local_def_id);
let opaque_hir_ty = match &self.hir().expect_item(opaque_hir_id).kind {
hir::ItemKind::OpaqueTy(opaque_hir_ty) => opaque_hir_ty,
_ => bug!("The HirId comes from a `ty::Opaque`"),
};

let (trait_ref, assoc_substs) = proj_ty.trait_ref_and_own_substs(self);

self.constrain_generic_bound_associated_type_structured_suggestion(
db,
self.def_span(def_id),
&assoc,
proj_ty.trait_ref_and_own_substs(self).1,
&trait_ref,
opaque_hir_ty.bounds,
assoc,
assoc_substs,
ty,
&msg,
msg,
true,
)
} else {
false
Expand Down Expand Up @@ -899,6 +912,11 @@ fn foo(&self) -> Self::T { String::new() }

/// Given a slice of `hir::GenericBound`s, if any of them corresponds to the `trait_ref`
/// requirement, provide a structured suggestion to constrain it to a given type `ty`.
///
/// `is_bound_surely_present` indicates whether we know the bound we're looking for is
/// inside `bounds`. If that's the case then we can consider `bounds` containing only one
/// trait bound as the one we're looking for. This can help in cases where the associated
/// type is defined on a supertrait of the one present in the bounds.
fn constrain_generic_bound_associated_type_structured_suggestion(
self,
db: &mut DiagnosticBuilder<'_>,
Expand All @@ -908,23 +926,30 @@ fn foo(&self) -> Self::T { String::new() }
assoc_substs: &[ty::GenericArg<'tcx>],
ty: Ty<'tcx>,
msg: &str,
is_bound_surely_present: bool,
) -> bool {
// FIXME: we would want to call `resolve_vars_if_possible` on `ty` before suggesting.
bounds.iter().any(|bound| match bound {
hir::GenericBound::Trait(ptr, hir::TraitBoundModifier::None) => {
// Relate the type param against `T` in `<A as T>::Foo`.
ptr.trait_ref.trait_def_id() == Some(trait_ref.def_id)
&& self.constrain_associated_type_structured_suggestion(
db,
ptr.span,
assoc,
assoc_substs,
ty,
msg,
)
}
_ => false,
})

let trait_bounds = bounds.iter().filter_map(|bound| match bound {
hir::GenericBound::Trait(ptr, hir::TraitBoundModifier::None) => Some(ptr),
_ => None,
});

let matching_trait_bounds = trait_bounds
.clone()
.filter(|ptr| ptr.trait_ref.trait_def_id() == Some(trait_ref.def_id))
.collect::<Vec<_>>();

let span = match &matching_trait_bounds[..] {
&[ptr] => ptr.span,
&[] if is_bound_surely_present => match &trait_bounds.collect::<Vec<_>>()[..] {
&[ptr] => ptr.span,
_ => return false,
},
_ => return false,
};

self.constrain_associated_type_structured_suggestion(db, span, assoc, assoc_substs, ty, msg)
}

/// Given a span corresponding to a bound, provide a structured suggestion to set an
Expand Down
10 changes: 0 additions & 10 deletions compiler/rustc_session/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,6 @@ pub struct Session {
/// Set of enabled features for the current target.
pub target_features: FxHashSet<Symbol>,

known_attrs: Lock<MarkedAttrs>,
used_attrs: Lock<MarkedAttrs>,

/// `Span`s for `if` conditions that we have suggested turning into `if let`.
Expand Down Expand Up @@ -1076,14 +1075,6 @@ impl Session {
== config::InstrumentCoverage::ExceptUnusedFunctions
}

pub fn mark_attr_known(&self, attr: &Attribute) {
self.known_attrs.lock().mark(attr)
}

pub fn is_attr_known(&self, attr: &Attribute) -> bool {
self.known_attrs.lock().is_marked(attr)
}

pub fn mark_attr_used(&self, attr: &Attribute) {
self.used_attrs.lock().mark(attr)
}
Expand Down Expand Up @@ -1389,7 +1380,6 @@ pub fn build_session(
miri_unleashed_features: Lock::new(Default::default()),
asm_arch,
target_features: FxHashSet::default(),
known_attrs: Lock::new(MarkedAttrs::new()),
used_attrs: Lock::new(MarkedAttrs::new()),
if_let_suggestions: Default::default(),
};
Expand Down
1 change: 1 addition & 0 deletions library/core/src/macros/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -845,6 +845,7 @@ pub(crate) mod builtin {
language use and is subject to change"
)]
#[allow_internal_unstable(fmt_internals)]
#[doc(hidden)]
#[rustc_builtin_macro]
#[macro_export]
macro_rules! format_args_nl {
Expand Down
1 change: 0 additions & 1 deletion library/core/src/mem/maybe_uninit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,6 @@ impl<T> MaybeUninit<T> {
/// With `write`, we can avoid the need to write through a raw pointer:
///
/// ```rust
/// #![feature(maybe_uninit_extra)]
/// use core::pin::Pin;
/// use core::mem::MaybeUninit;
///
Expand Down
7 changes: 3 additions & 4 deletions library/std/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ impl Error for VarError {
}
}

/// Sets the environment variable `k` to the value `v` for the currently running
/// Sets the environment variable `key` to the value `value` for the currently running
/// process.
///
/// Note that while concurrent access to environment variables is safe in Rust,
Expand All @@ -310,9 +310,8 @@ impl Error for VarError {
///
/// # Panics
///
/// This function may panic if `key` is empty, contains an ASCII equals sign
/// `'='` or the NUL character `'\0'`, or when the value contains the NUL
/// character.
/// This function may panic if `key` is empty, contains an ASCII equals sign `'='`
/// or the NUL character `'\0'`, or when `value` contains the NUL character.
///
/// # Examples
///
Expand Down
99 changes: 99 additions & 0 deletions src/test/ui/associated-types/issue-87261.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
trait Foo {}

trait Trait {
type Associated;
}
trait DerivedTrait: Trait {}
trait GenericTrait<A> {
type Associated;
}

struct Impl;
impl Foo for Impl {}
impl Trait for Impl {
type Associated = ();
}
impl DerivedTrait for Impl {}
impl<A> GenericTrait<A> for Impl {
type Associated = ();
}

fn returns_opaque() -> impl Trait + 'static {
Impl
}
fn returns_opaque_derived() -> impl DerivedTrait + 'static {
Impl
}
fn returns_opaque_foo() -> impl Trait + Foo {
Impl
}
fn returns_opaque_derived_foo() -> impl DerivedTrait + Foo {
Impl
}
fn returns_opaque_generic() -> impl GenericTrait<()> + 'static {
Impl
}
fn returns_opaque_generic_foo() -> impl GenericTrait<()> + Foo {
Impl
}
fn returns_opaque_generic_duplicate() -> impl GenericTrait<()> + GenericTrait<u8> {
Impl
}

fn accepts_trait<T: Trait<Associated = ()>>(_: T) {}
fn accepts_generic_trait<T: GenericTrait<(), Associated = ()>>(_: T) {}

fn check_generics<A, B, C, D, E, F, G>(a: A, b: B, c: C, d: D, e: E, f: F, g: G)
where
A: Trait + 'static,
B: DerivedTrait + 'static,
C: Trait + Foo,
D: DerivedTrait + Foo,
E: GenericTrait<()> + 'static,
F: GenericTrait<()> + Foo,
G: GenericTrait<()> + GenericTrait<u8>,
{
accepts_trait(a);
//~^ ERROR type mismatch resolving `<A as Trait>::Associated == ()`

accepts_trait(b);
//~^ ERROR type mismatch resolving `<B as Trait>::Associated == ()`

accepts_trait(c);
//~^ ERROR type mismatch resolving `<C as Trait>::Associated == ()`

accepts_trait(d);
//~^ ERROR type mismatch resolving `<D as Trait>::Associated == ()`

accepts_generic_trait(e);
//~^ ERROR type mismatch resolving `<E as GenericTrait<()>>::Associated == ()`

accepts_generic_trait(f);
//~^ ERROR type mismatch resolving `<F as GenericTrait<()>>::Associated == ()`

accepts_generic_trait(g);
//~^ ERROR type mismatch resolving `<G as GenericTrait<()>>::Associated == ()`
}

fn main() {
accepts_trait(returns_opaque());
//~^ ERROR type mismatch resolving `<impl Trait as Trait>::Associated == ()`

accepts_trait(returns_opaque_derived());
//~^ ERROR type mismatch resolving `<impl DerivedTrait as Trait>::Associated == ()`

accepts_trait(returns_opaque_foo());
//~^ ERROR type mismatch resolving `<impl Trait+Foo as Trait>::Associated == ()`

accepts_trait(returns_opaque_derived_foo());
//~^ ERROR type mismatch resolving `<impl DerivedTrait+Foo as Trait>::Associated == ()`

accepts_generic_trait(returns_opaque_generic());
//~^ ERROR type mismatch resolving `<impl GenericTrait<()> as GenericTrait<()>>::Associated == ()`

accepts_generic_trait(returns_opaque_generic_foo());
//~^ ERROR type mismatch resolving `<impl GenericTrait<()>+Foo as GenericTrait<()>>::Associated == ()`

accepts_generic_trait(returns_opaque_generic_duplicate());
//~^ ERROR type mismatch resolving `<impl GenericTrait<()>+GenericTrait<u8> as GenericTrait<()>>::Associated == ()`
}
Loading