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 6 pull requests #96398

Closed
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
13 changes: 0 additions & 13 deletions compiler/rustc_errors/src/diagnostic_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,19 +255,6 @@ impl EmissionGuarantee for ! {
/// instead of a `&DiagnosticBuilder<'a>`. This `forward!` macro makes
/// it easy to declare such methods on the builder.
macro_rules! forward {
// Forward pattern for &self -> &Self
(
$(#[$attrs:meta])*
pub fn $n:ident(&self, $($name:ident: $ty:ty),* $(,)?) -> &Self
) => {
$(#[$attrs])*
#[doc = concat!("See [`Diagnostic::", stringify!($n), "()`].")]
pub fn $n(&self, $($name: $ty),*) -> &Self {
self.diagnostic.$n($($name),*);
self
}
};

// Forward pattern for &mut self -> &mut Self
(
$(#[$attrs:meta])*
Expand Down
3 changes: 0 additions & 3 deletions compiler/rustc_middle/src/ty/codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -453,9 +453,6 @@ macro_rules! impl_arena_allocatable_decoder {
}
}
};
([$ignore:ident $(, $attrs:ident)*]$args:tt) => {
impl_arena_allocatable_decoder!([$($attrs),*]$args);
};
}

macro_rules! impl_arena_allocatable_decoders {
Expand Down
43 changes: 34 additions & 9 deletions compiler/rustc_parse/src/parser/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -431,10 +431,11 @@ impl<'a> Parser<'a> {
return Ok(true);
} else if self.look_ahead(0, |t| {
t == &token::CloseDelim(token::Brace)
|| (
t.can_begin_expr() && t != &token::Semi && t != &token::Pound
// Avoid triggering with too many trailing `#` in raw string.
)
|| (t.can_begin_expr() && t != &token::Semi && t != &token::Pound)
// Avoid triggering with too many trailing `#` in raw string.
|| (sm.is_multiline(
self.prev_token.span.shrink_to_hi().until(self.token.span.shrink_to_lo())
) && t == &token::Pound)
}) {
// Missing semicolon typo. This is triggered if the next token could either start a
// new statement or is a block close. For example:
Expand Down Expand Up @@ -508,7 +509,12 @@ impl<'a> Parser<'a> {
}

if self.check_too_many_raw_str_terminators(&mut err) {
return Err(err);
if expected.contains(&TokenType::Token(token::Semi)) && self.eat(&token::Semi) {
err.emit();
return Ok(true);
} else {
return Err(err);
}
}

if self.prev_token.span == DUMMY_SP {
Expand Down Expand Up @@ -538,22 +544,41 @@ impl<'a> Parser<'a> {
}

fn check_too_many_raw_str_terminators(&mut self, err: &mut Diagnostic) -> bool {
let sm = self.sess.source_map();
match (&self.prev_token.kind, &self.token.kind) {
(
TokenKind::Literal(Lit {
kind: LitKind::StrRaw(n_hashes) | LitKind::ByteStrRaw(n_hashes),
..
}),
TokenKind::Pound,
) => {
) if !sm.is_multiline(
self.prev_token.span.shrink_to_hi().until(self.token.span.shrink_to_lo()),
) =>
{
let n_hashes: u8 = *n_hashes;
err.set_primary_message("too many `#` when terminating raw string");
let str_span = self.prev_token.span;
let mut span = self.token.span;
let mut count = 0;
while self.token.kind == TokenKind::Pound
&& !sm.is_multiline(span.shrink_to_hi().until(self.token.span.shrink_to_lo()))
{
span = span.with_hi(self.token.span.hi());
self.bump();
count += 1;
}
err.set_span(span);
err.span_suggestion(
self.token.span,
"remove the extra `#`",
span,
&format!("remove the extra `#`{}", pluralize!(count)),
String::new(),
Applicability::MachineApplicable,
);
err.note(&format!("the raw string started with {n_hashes} `#`s"));
err.span_label(
str_span,
&format!("this raw string started with {n_hashes} `#`{}", pluralize!(n_hashes)),
);
true
}
_ => false,
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_serialize/src/serialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,6 @@ macro_rules! peel {
/// Therefore, the recursion depth is the binary logarithm of the number of
/// tokens to count, and the expanded tree is likewise very small.
macro_rules! count {
() => (0usize);
($one:tt) => (1usize);
($($pairs:tt $_p:tt)*) => (count!($($pairs)*) << 1usize);
($odd:tt $($rest:tt)*) => (count!($($rest)*) | 1usize);
Expand Down
4 changes: 0 additions & 4 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2249,10 +2249,6 @@ impl ToJson for Target {
let name = (stringify!($attr)).replace("_", "-");
d.insert(name, self.$attr.to_json());
}};
($attr:ident, $key_name:expr) => {{
let name = $key_name;
d.insert(name.into(), self.$attr.to_json());
}};
}

macro_rules! target_option_val {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1727,6 +1727,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
} else if cat_a == cat_b {
match (a.kind(), b.kind()) {
(ty::Adt(def_a, _), ty::Adt(def_b, _)) => def_a == def_b,
(ty::Foreign(def_a), ty::Foreign(def_b)) => def_a == def_b,
// Matching on references results in a lot of unhelpful
// suggestions, so let's just not do that for now.
//
Expand Down
52 changes: 28 additions & 24 deletions compiler/rustc_typeck/src/check/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// While we don't allow *arbitrary* coercions here, we *do* allow
// coercions from ! to `expected`.
if ty.is_never() {
assert!(
!self.typeck_results.borrow().adjustments().contains_key(expr.hir_id),
"expression with never type wound up being adjusted"
);
if let Some(adjustments) = self.typeck_results.borrow().adjustments().get(expr.hir_id) {
self.tcx().sess.delay_span_bug(
expr.span,
"expression with never type wound up being adjusted",
);
return if let [Adjustment { kind: Adjust::NeverToAny, target }] = &adjustments[..] {
target.to_owned()
} else {
self.tcx().ty_error()
};
}

let adj_ty = self.next_ty_var(TypeVariableOrigin {
kind: TypeVariableOriginKind::AdjustmentType,
span: expr.span,
Expand Down Expand Up @@ -2277,14 +2285,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// try to add a suggestion in case the field is a nested field of a field of the Adt
if let Some((fields, substs)) = self.get_field_candidates(span, expr_t) {
for candidate_field in fields.iter() {
if let Some(field_path) = self.check_for_nested_field(
if let Some(mut field_path) = self.check_for_nested_field_satisfying(
span,
field,
&|candidate_field, _| candidate_field.ident(self.tcx()) == field,
candidate_field,
substs,
vec![],
self.tcx.parent_module(id).to_def_id(),
) {
// field_path includes `field` that we're looking for, so pop it.
field_path.pop();

let field_path_str = field_path
.iter()
.map(|id| id.name.to_ident_string())
Expand All @@ -2304,7 +2315,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
err
}

fn get_field_candidates(
crate fn get_field_candidates(
&self,
span: Span,
base_t: Ty<'tcx>,
Expand All @@ -2329,49 +2340,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

/// This method is called after we have encountered a missing field error to recursively
/// search for the field
fn check_for_nested_field(
crate fn check_for_nested_field_satisfying(
&self,
span: Span,
target_field: Ident,
matches: &impl Fn(&ty::FieldDef, Ty<'tcx>) -> bool,
candidate_field: &ty::FieldDef,
subst: SubstsRef<'tcx>,
mut field_path: Vec<Ident>,
id: DefId,
) -> Option<Vec<Ident>> {
debug!(
"check_for_nested_field(span: {:?}, candidate_field: {:?}, field_path: {:?}",
"check_for_nested_field_satisfying(span: {:?}, candidate_field: {:?}, field_path: {:?}",
span, candidate_field, field_path
);

if candidate_field.ident(self.tcx) == target_field {
Some(field_path)
} else if field_path.len() > 3 {
if field_path.len() > 3 {
// For compile-time reasons and to avoid infinite recursion we only check for fields
// up to a depth of three
None
} else {
// recursively search fields of `candidate_field` if it's a ty::Adt

field_path.push(candidate_field.ident(self.tcx).normalize_to_macros_2_0());
let field_ty = candidate_field.ty(self.tcx, subst);
if let Some((nested_fields, subst)) = self.get_field_candidates(span, field_ty) {
for field in nested_fields.iter() {
let accessible = field.vis.is_accessible_from(id, self.tcx);
if accessible {
let ident = field.ident(self.tcx).normalize_to_macros_2_0();
if ident == target_field {
if field.vis.is_accessible_from(id, self.tcx) {
if matches(candidate_field, field_ty) {
return Some(field_path);
}
let field_path = field_path.clone();
if let Some(path) = self.check_for_nested_field(
} else if let Some(field_path) = self.check_for_nested_field_satisfying(
span,
target_field,
matches,
field,
subst,
field_path,
field_path.clone(),
id,
) {
return Some(path);
return Some(field_path);
}
}
}
Expand Down
42 changes: 41 additions & 1 deletion compiler/rustc_typeck/src/check/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use rustc_trait_selection::traits::{
use std::cmp::Ordering;
use std::iter;

use super::probe::Mode;
use super::probe::{Mode, ProbeScope};
use super::{CandidateSource, MethodError, NoMatchData};

impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Expand Down Expand Up @@ -1129,6 +1129,46 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
label_span_not_found();
}

if let SelfSource::MethodCall(expr) = source
&& let Some((fields, substs)) = self.get_field_candidates(span, actual)
{
let call_expr =
self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(expr.hir_id));
for candidate_field in fields.iter() {
if let Some(field_path) = self.check_for_nested_field_satisfying(
span,
&|_, field_ty| {
self.lookup_probe(
span,
item_name,
field_ty,
call_expr,
ProbeScope::AllTraits,
)
.is_ok()
},
candidate_field,
substs,
vec![],
self.tcx.parent_module(expr.hir_id).to_def_id(),
) {
let field_path_str = field_path
.iter()
.map(|id| id.name.to_ident_string())
.collect::<Vec<String>>()
.join(".");
debug!("field_path_str: {:?}", field_path_str);

err.span_suggestion_verbose(
item_name.span.shrink_to_lo(),
"one of the expressions' fields has a method of the same name",
format!("{field_path_str}."),
Applicability::MaybeIncorrect,
);
}
}
}

bound_spans.sort();
bound_spans.dedup();
for (span, msg) in bound_spans.into_iter() {
Expand Down
10 changes: 5 additions & 5 deletions library/alloc/src/collections/linked_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,7 @@ impl<T> LinkedList<T> {
/// Returns `true` if the `LinkedList` contains an element equal to the
/// given value.
///
/// This operation should compute in *O*(*n*) time.
/// This operation should compute linearly in *O*(*n*) time.
///
/// # Examples
///
Expand Down Expand Up @@ -1569,7 +1569,7 @@ impl<'a, T> CursorMut<'a, T> {
/// Appends an element to the front of the cursor's parent list. The node
/// that the cursor points to is unchanged, even if it is the "ghost" node.
///
/// This operation should compute in O(1) time.
/// This operation should compute in *O*(1) time.
// `push_front` continues to point to "ghost" when it addes a node to mimic
// the behavior of `insert_before` on an empty list.
#[unstable(feature = "linked_list_cursors", issue = "58533")]
Expand All @@ -1584,7 +1584,7 @@ impl<'a, T> CursorMut<'a, T> {
/// Appends an element to the back of the cursor's parent list. The node
/// that the cursor points to is unchanged, even if it is the "ghost" node.
///
/// This operation should compute in O(1) time.
/// This operation should compute in *O*(1) time.
#[unstable(feature = "linked_list_cursors", issue = "58533")]
pub fn push_back(&mut self, elt: T) {
// Safety: We know that `push_back` does not change the position in
Expand All @@ -1603,7 +1603,7 @@ impl<'a, T> CursorMut<'a, T> {
/// unchanged, unless it was pointing to the front element. In that case, it
/// points to the new front element.
///
/// This operation should compute in O(1) time.
/// This operation should compute in *O*(1) time.
#[unstable(feature = "linked_list_cursors", issue = "58533")]
pub fn pop_front(&mut self) -> Option<T> {
// We can't check if current is empty, we must check the list directly.
Expand All @@ -1630,7 +1630,7 @@ impl<'a, T> CursorMut<'a, T> {
/// unchanged, unless it was pointing to the back element. In that case, it
/// points to the "ghost" element.
///
/// This operation should compute in O(1) time.
/// This operation should compute in *O*(1) time.
#[unstable(feature = "linked_list_cursors", issue = "58533")]
pub fn pop_back(&mut self) -> Option<T> {
if self.list.is_empty() {
Expand Down
Loading