Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
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
9 changes: 7 additions & 2 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3901,12 +3901,17 @@ pub struct Delegation {
pub from_glob: bool,
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub enum DelegationSuffixes {
List(ThinVec<(Ident, Option<Ident>)>),
Glob(Span),
}

#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct DelegationMac {
pub qself: Option<Box<QSelf>>,
pub prefix: Path,
// Some for list delegation, and None for glob delegation.
pub suffixes: Option<ThinVec<(Ident, Option<Ident>)>>,
pub suffixes: DelegationSuffixes,
pub body: Option<Box<Block>>,
}

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_ast/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,7 @@ macro_rules! common_visitor_and_walkers {
Defaultness,
Delegation,
DelegationMac,
DelegationSuffixes,
DelimArgs,
DelimSpan,
EnumDef,
Expand Down
10 changes: 8 additions & 2 deletions compiler/rustc_ast_pretty/src/pprust/state/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,10 @@ impl<'a> State<'a> {
&item.vis,
&deleg.qself,
&deleg.prefix,
deleg.suffixes.as_ref().map_or(DelegationKind::Glob, |s| DelegationKind::List(s)),
match &deleg.suffixes {
ast::DelegationSuffixes::List(s) => DelegationKind::List(s),
ast::DelegationSuffixes::Glob(_) => DelegationKind::Glob,
},
&deleg.body,
),
}
Expand Down Expand Up @@ -651,7 +654,10 @@ impl<'a> State<'a> {
vis,
&deleg.qself,
&deleg.prefix,
deleg.suffixes.as_ref().map_or(DelegationKind::Glob, |s| DelegationKind::List(s)),
match &deleg.suffixes {
ast::DelegationSuffixes::List(s) => DelegationKind::List(s),
ast::DelegationSuffixes::Glob(_) => DelegationKind::Glob,
},
&deleg.body,
),
}
Expand Down
9 changes: 9 additions & 0 deletions compiler/rustc_borrowck/src/type_check/input_output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
return;
}

// If the MIR body was constructed via `construct_error` (because an
// earlier pass like match checking failed), its args may not match
// the user-provided signature (e.g. a coroutine with too many
// parameters). Bail out as this can cause panic,
// see <https://github.com/rust-lang/rust/issues/139570>.
if self.body.tainted_by_errors.is_some() {
return;
}

let user_provided_poly_sig = self.tcx().closure_user_provided_sig(mir_def_id);

// Instantiate the canonicalized variables from user-provided signature
Expand Down
10 changes: 2 additions & 8 deletions compiler/rustc_errors/src/markdown/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ fn parse_heading(buf: &[u8]) -> ParseResult<'_> {
fn parse_unordered_li(buf: &[u8]) -> Parsed<'_> {
let (txt, rest) = get_indented_section(&buf[2..]);
let ctx = Context { .. };
let stream = parse_recursive(trim_ascii_start(txt), ctx);
let stream = parse_recursive(txt.trim_ascii_start(), ctx);
(MdTree::UnorderedListItem(stream), rest)
}

Expand All @@ -261,7 +261,7 @@ fn parse_ordered_li(buf: &[u8]) -> Parsed<'_> {
let (num, pos) = ord_list_start(buf).unwrap(); // success tested in caller
let (txt, rest) = get_indented_section(&buf[pos..]);
let ctx = Context { .. };
let stream = parse_recursive(trim_ascii_start(txt), ctx);
let stream = parse_recursive(txt.trim_ascii_start(), ctx);
(MdTree::OrderedListItem(num, stream), rest)
}

Expand Down Expand Up @@ -578,12 +578,6 @@ fn trim_extra_ws(mut txt: &str) -> &str {
&txt[..txt.len() - end_ws]
}

/// If there is more than one whitespace char at start, trim the extras
fn trim_ascii_start(buf: &[u8]) -> &[u8] {
let count = buf.iter().take_while(|ch| ch.is_ascii_whitespace()).count();
&buf[count..]
}

#[cfg(test)]
#[path = "tests/parse.rs"]
mod tests;
21 changes: 21 additions & 0 deletions compiler/rustc_errors/src/markdown/tests/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,3 +377,24 @@ fn test_codeblock_trailing_whitespace() {
assert_eq!(t, MdTree::CodeBlock { txt: "code\n```abc\nrest", lang: Some("rust") });
assert_eq!(r, b"");
}

#[test]
fn test_list_item_leading_whitespace() {
// extra spaces after marker
let buf = "- hello";
let (t, r) = parse_unordered_li(buf.as_bytes());
assert_eq!(t, MdTree::UnorderedListItem(vec![MdTree::PlainText("hello")].into()));
assert_eq!(r, b"");

// tab after the marker space
let buf = "- \thello";
let (t, r) = parse_unordered_li(buf.as_bytes());
assert_eq!(t, MdTree::UnorderedListItem(vec![MdTree::PlainText("hello")].into()));
assert_eq!(r, b"");

// ordered list
let buf = "1. hello";
let (t, r) = parse_ordered_li(buf.as_bytes());
assert_eq!(t, MdTree::OrderedListItem(1, vec![MdTree::PlainText("hello")].into()));
assert_eq!(r, b"");
}
11 changes: 9 additions & 2 deletions compiler/rustc_expand/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1019,26 +1019,32 @@ impl SyntaxExtension {
pub fn glob_delegation(
trait_def_id: DefId,
impl_def_id: LocalDefId,
star_span: Span,
edition: Edition,
) -> SyntaxExtension {
struct GlobDelegationExpanderImpl {
trait_def_id: DefId,
impl_def_id: LocalDefId,
star_span: Span,
}
impl GlobDelegationExpander for GlobDelegationExpanderImpl {
fn expand(
&self,
ecx: &mut ExtCtxt<'_>,
) -> ExpandResult<Vec<(Ident, Option<Ident>)>, ()> {
match ecx.resolver.glob_delegation_suffixes(self.trait_def_id, self.impl_def_id) {
match ecx.resolver.glob_delegation_suffixes(
self.trait_def_id,
self.impl_def_id,
self.star_span,
) {
Ok(suffixes) => ExpandResult::Ready(suffixes),
Err(Indeterminate) if ecx.force_mode => ExpandResult::Ready(Vec::new()),
Err(Indeterminate) => ExpandResult::Retry(()),
}
}
}

let expander = GlobDelegationExpanderImpl { trait_def_id, impl_def_id };
let expander = GlobDelegationExpanderImpl { trait_def_id, impl_def_id, star_span };
SyntaxExtension::default(SyntaxExtensionKind::GlobDelegation(Arc::new(expander)), edition)
}

Expand Down Expand Up @@ -1170,6 +1176,7 @@ pub trait ResolverExpand {
&self,
trait_def_id: DefId,
impl_def_id: LocalDefId,
star_span: Span,
) -> Result<Vec<(Ident, Option<Ident>)>, Indeterminate>;

/// Record the name of an opaque `Ty::ImplTrait` pre-expansion so that it can be used
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_expand/src/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ use rustc_ast::tokenstream::TokenStream;
use rustc_ast::visit::{self, AssocCtxt, Visitor, VisitorResult, try_visit, walk_list};
use rustc_ast::{
self as ast, AssocItemKind, AstNodeWrapper, AttrArgs, AttrItemKind, AttrStyle, AttrVec,
DUMMY_NODE_ID, EarlyParsedAttribute, ExprKind, ForeignItemKind, HasAttrs, HasNodeId, Inline,
ItemKind, MacStmtStyle, MetaItemInner, MetaItemKind, ModKind, NodeId, PatKind, StmtKind,
TyKind, token,
DUMMY_NODE_ID, DelegationSuffixes, EarlyParsedAttribute, ExprKind, ForeignItemKind, HasAttrs,
HasNodeId, Inline, ItemKind, MacStmtStyle, MetaItemInner, MetaItemKind, ModKind, NodeId,
PatKind, StmtKind, TyKind, token,
};
use rustc_ast_pretty::pprust;
use rustc_attr_parsing::parser::AllowExprMetavar;
Expand Down Expand Up @@ -2401,7 +2401,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
res
}
None if let Some((deleg, item)) = node.delegation() => {
let Some(suffixes) = &deleg.suffixes else {
let DelegationSuffixes::List(suffixes) = &deleg.suffixes else {
let traitless_qself =
matches!(&deleg.qself, Some(qself) if qself.position == 0);
let (item, of_trait) = match node.to_annotatable() {
Expand Down
13 changes: 10 additions & 3 deletions compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -659,9 +659,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// being stalled on a coroutine.
self.select_obligations_where_possible(|_| {});

let ty::TypingMode::Analysis { defining_opaque_types_and_generators } = self.typing_mode()
else {
bug!();
let defining_opaque_types_and_generators = match self.typing_mode() {
ty::TypingMode::Analysis { defining_opaque_types_and_generators } => {
defining_opaque_types_and_generators
}
ty::TypingMode::Coherence
| ty::TypingMode::Borrowck { .. }
| ty::TypingMode::PostBorrowckAnalysis { .. }
| ty::TypingMode::PostAnalysis => {
bug!()
}
};

if defining_opaque_types_and_generators
Expand Down
16 changes: 12 additions & 4 deletions compiler/rustc_hir_typeck/src/opaque_types.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use rustc_hir::def::DefKind;
use rustc_infer::traits::ObligationCause;
use rustc_middle::bug;
use rustc_middle::ty::{
self, DefiningScopeKind, DefinitionSiteHiddenType, OpaqueTypeKey, ProvisionalHiddenType,
TypeVisitableExt, TypingMode,
TypeVisitableExt,
};
use rustc_trait_selection::error_reporting::infer::need_type_info::TypeAnnotationNeeded;
use rustc_trait_selection::opaque_types::{
Expand Down Expand Up @@ -97,9 +98,16 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
debug!(?opaque_types);

let tcx = self.tcx;
let TypingMode::Analysis { defining_opaque_types_and_generators } = self.typing_mode()
else {
unreachable!();
let defining_opaque_types_and_generators = match self.typing_mode() {
ty::TypingMode::Analysis { defining_opaque_types_and_generators } => {
defining_opaque_types_and_generators
}
ty::TypingMode::Coherence
| ty::TypingMode::Borrowck { .. }
| ty::TypingMode::PostBorrowckAnalysis { .. }
| ty::TypingMode::PostAnalysis => {
bug!()
}
};

for def_id in defining_opaque_types_and_generators {
Expand Down
26 changes: 24 additions & 2 deletions compiler/rustc_lint/src/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -783,15 +783,37 @@ impl<'tcx> LateLintPass<'tcx> for RustcMustMatchExhaustively {
}
}
}
hir::ExprKind::If(expr, ..) if let ExprKind::Let(expr) = expr.kind => {
hir::ExprKind::Let(expr, ..) => {
if let Some(attr_span) = is_rustc_must_match_exhaustively(cx, expr.init.hir_id) {
cx.emit_span_lint(
RUSTC_MUST_MATCH_EXHAUSTIVELY,
expr.span,
RustcMustMatchExhaustivelyNotExhaustive {
attr_span,
pat_span: expr.span,
message: "using if let only matches on one variant (try using `match`)",
message: "using `if let` only matches on one variant (try using `match`)",
},
);
}
}
_ => {}
}
}

fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx rustc_hir::Stmt<'tcx>) {
match stmt.kind {
rustc_hir::StmtKind::Let(let_stmt) => {
if let_stmt.els.is_some()
&& let Some(attr_span) =
is_rustc_must_match_exhaustively(cx, let_stmt.pat.hir_id)
{
cx.emit_span_lint(
RUSTC_MUST_MATCH_EXHAUSTIVELY,
let_stmt.span,
RustcMustMatchExhaustivelyNotExhaustive {
attr_span,
pat_span: let_stmt.pat.span,
message: "using `let else` only matches on one variant (try using `match`)",
},
);
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ where
// normalizing the self type as well, since type variables are not uniquified.
let goal = self.resolve_vars_if_possible(goal);

if let TypingMode::Coherence = self.typing_mode()
if self.typing_mode().is_coherence()
&& let Ok(candidate) = self.consider_coherence_unknowable_candidate(goal)
{
candidates.push(candidate);
Expand Down
13 changes: 9 additions & 4 deletions compiler/rustc_parse/src/parser/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -857,7 +857,7 @@ impl<'a> Parser<'a> {
kind: AssocItemKind::DelegationMac(Box::new(DelegationMac {
qself: None,
prefix: of_trait.trait_ref.path.clone(),
suffixes: None,
suffixes: DelegationSuffixes::Glob(whole_reuse_span),
body,
})),
}));
Expand All @@ -879,10 +879,12 @@ impl<'a> Parser<'a> {

Ok(if self.eat_path_sep() {
let suffixes = if self.eat(exp!(Star)) {
None
DelegationSuffixes::Glob(self.prev_token.span)
} else {
let parse_suffix = |p: &mut Self| Ok((p.parse_path_segment_ident()?, rename(p)?));
Some(self.parse_delim_comma_seq(exp!(OpenBrace), exp!(CloseBrace), parse_suffix)?.0)
DelegationSuffixes::List(
self.parse_delim_comma_seq(exp!(OpenBrace), exp!(CloseBrace), parse_suffix)?.0,
)
};

ItemKind::DelegationMac(Box::new(DelegationMac {
Expand Down Expand Up @@ -1519,7 +1521,10 @@ impl<'a> Parser<'a> {
let span = self.psess.source_map().guess_head_span(span);
let descr = kind.descr();
let help = match kind {
ItemKind::DelegationMac(deleg) if deleg.suffixes.is_none() => false,
ItemKind::DelegationMac(box DelegationMac {
suffixes: DelegationSuffixes::Glob(_),
..
}) => false,
_ => true,
};
self.dcx().emit_err(errors::BadItemKind { span, descr, ctx, help });
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3872,8 +3872,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {

let Some(body) = &delegation.body else { return };
self.with_rib(ValueNS, RibKind::FnOrCoroutine, |this| {
let span = delegation.path.segments.last().unwrap().ident.span;
let ident = Ident::new(kw::SelfLower, span.normalize_to_macro_rules());
let ident = Ident::new(kw::SelfLower, body.span.normalize_to_macro_rules());
let res = Res::Local(delegation.id);
this.innermost_rib_bindings(ValueNS).insert(ident, res);

Expand Down
Loading
Loading