Skip to content

Commit 29457dd

Browse files
committed
Auto merge of rust-lang#71958 - Dylan-DPC:rollup-woxwt5d, r=Dylan-DPC
Rollup of 5 pull requests Successful merges: - rust-lang#70908 (Provide suggestions for type parameters missing bounds for associated types) - rust-lang#71731 (Turn off rustc-dev-guide toolstate for now) - rust-lang#71888 (refactor suggest_traits_to_import) - rust-lang#71918 (Rename methods section) - rust-lang#71950 (Miri validation error handling cleanup) Failed merges: r? @ghost
2 parents 1836e3b + 066eb08 commit 29457dd

File tree

38 files changed

+950
-485
lines changed

38 files changed

+950
-485
lines changed

src/bootstrap/toolstate.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ static STABLE_TOOLS: &[(&str, &str)] = &[
8888
static NIGHTLY_TOOLS: &[(&str, &str)] = &[
8989
("miri", "src/tools/miri"),
9090
("embedded-book", "src/doc/embedded-book"),
91-
("rustc-dev-guide", "src/doc/rustc-dev-guide"),
91+
// ("rustc-dev-guide", "src/doc/rustc-dev-guide"),
9292
];
9393

9494
fn print_error(tool: &str, submodule: &str) {

src/ci/docker/x86_64-gnu-tools/checktools.sh

-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ python3 "$X_PY" test --no-fail-fast \
1414
src/doc/rust-by-example \
1515
src/doc/embedded-book \
1616
src/doc/edition-guide \
17-
src/doc/rustc-dev-guide \
1817
src/tools/clippy \
1918
src/tools/rls \
2019
src/tools/rustfmt \

src/librustc_ast_passes/ast_validation.rs

+85-11
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use rustc_session::Session;
2323
use rustc_span::symbol::{kw, sym};
2424
use rustc_span::Span;
2525
use std::mem;
26+
use std::ops::DerefMut;
2627

2728
const MORE_EXTERN: &str =
2829
"for more information, visit https://doc.rust-lang.org/std/keyword.extern.html";
@@ -1113,17 +1114,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
11131114

11141115
for predicate in &generics.where_clause.predicates {
11151116
if let WherePredicate::EqPredicate(ref predicate) = *predicate {
1116-
self.err_handler()
1117-
.struct_span_err(
1118-
predicate.span,
1119-
"equality constraints are not yet supported in `where` clauses",
1120-
)
1121-
.span_label(predicate.span, "not supported")
1122-
.note(
1123-
"see issue #20041 <https://github.com/rust-lang/rust/issues/20041> \
1124-
for more information",
1125-
)
1126-
.emit();
1117+
deny_equality_constraints(self, predicate, generics);
11271118
}
11281119
}
11291120

@@ -1300,6 +1291,89 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
13001291
}
13011292
}
13021293

1294+
/// When encountering an equality constraint in a `where` clause, emit an error. If the code seems
1295+
/// like it's setting an associated type, provide an appropriate suggestion.
1296+
fn deny_equality_constraints(
1297+
this: &mut AstValidator<'_>,
1298+
predicate: &WhereEqPredicate,
1299+
generics: &Generics,
1300+
) {
1301+
let mut err = this.err_handler().struct_span_err(
1302+
predicate.span,
1303+
"equality constraints are not yet supported in `where` clauses",
1304+
);
1305+
err.span_label(predicate.span, "not supported");
1306+
1307+
// Given `<A as Foo>::Bar = RhsTy`, suggest `A: Foo<Bar = RhsTy>`.
1308+
if let TyKind::Path(Some(qself), full_path) = &predicate.lhs_ty.kind {
1309+
if let TyKind::Path(None, path) = &qself.ty.kind {
1310+
match &path.segments[..] {
1311+
[PathSegment { ident, args: None, .. }] => {
1312+
for param in &generics.params {
1313+
if param.ident == *ident {
1314+
let param = ident;
1315+
match &full_path.segments[qself.position..] {
1316+
[PathSegment { ident, .. }] => {
1317+
// Make a new `Path` from `foo::Bar` to `Foo<Bar = RhsTy>`.
1318+
let mut assoc_path = full_path.clone();
1319+
// Remove `Bar` from `Foo::Bar`.
1320+
assoc_path.segments.pop();
1321+
let len = assoc_path.segments.len() - 1;
1322+
// Build `<Bar = RhsTy>`.
1323+
let arg = AngleBracketedArg::Constraint(AssocTyConstraint {
1324+
id: rustc_ast::node_id::DUMMY_NODE_ID,
1325+
ident: *ident,
1326+
kind: AssocTyConstraintKind::Equality {
1327+
ty: predicate.rhs_ty.clone(),
1328+
},
1329+
span: ident.span,
1330+
});
1331+
// Add `<Bar = RhsTy>` to `Foo`.
1332+
match &mut assoc_path.segments[len].args {
1333+
Some(args) => match args.deref_mut() {
1334+
GenericArgs::Parenthesized(_) => continue,
1335+
GenericArgs::AngleBracketed(args) => {
1336+
args.args.push(arg);
1337+
}
1338+
},
1339+
empty_args => {
1340+
*empty_args = AngleBracketedArgs {
1341+
span: ident.span,
1342+
args: vec![arg],
1343+
}
1344+
.into();
1345+
}
1346+
}
1347+
err.span_suggestion_verbose(
1348+
predicate.span,
1349+
&format!(
1350+
"if `{}` is an associated type you're trying to set, \
1351+
use the associated type binding syntax",
1352+
ident
1353+
),
1354+
format!(
1355+
"{}: {}",
1356+
param,
1357+
pprust::path_to_string(&assoc_path)
1358+
),
1359+
Applicability::MaybeIncorrect,
1360+
);
1361+
}
1362+
_ => {}
1363+
};
1364+
}
1365+
}
1366+
}
1367+
_ => {}
1368+
}
1369+
}
1370+
}
1371+
err.note(
1372+
"see issue #20041 <https://github.com/rust-lang/rust/issues/20041> for more information",
1373+
);
1374+
err.emit();
1375+
}
1376+
13031377
pub fn check_crate(session: &Session, krate: &Crate, lints: &mut LintBuffer) -> bool {
13041378
let mut validator = AstValidator {
13051379
session,

src/librustc_hir/hir.rs

+35-1
Original file line numberDiff line numberDiff line change
@@ -2626,8 +2626,42 @@ impl Node<'_> {
26262626
match self {
26272627
Node::TraitItem(TraitItem { generics, .. })
26282628
| Node::ImplItem(ImplItem { generics, .. })
2629-
| Node::Item(Item { kind: ItemKind::Fn(_, generics, _), .. }) => Some(generics),
2629+
| Node::Item(Item {
2630+
kind:
2631+
ItemKind::Trait(_, _, generics, ..)
2632+
| ItemKind::Impl { generics, .. }
2633+
| ItemKind::Fn(_, generics, _),
2634+
..
2635+
}) => Some(generics),
26302636
_ => None,
26312637
}
26322638
}
2639+
2640+
pub fn hir_id(&self) -> Option<HirId> {
2641+
match self {
2642+
Node::Item(Item { hir_id, .. })
2643+
| Node::ForeignItem(ForeignItem { hir_id, .. })
2644+
| Node::TraitItem(TraitItem { hir_id, .. })
2645+
| Node::ImplItem(ImplItem { hir_id, .. })
2646+
| Node::Field(StructField { hir_id, .. })
2647+
| Node::AnonConst(AnonConst { hir_id, .. })
2648+
| Node::Expr(Expr { hir_id, .. })
2649+
| Node::Stmt(Stmt { hir_id, .. })
2650+
| Node::Ty(Ty { hir_id, .. })
2651+
| Node::Binding(Pat { hir_id, .. })
2652+
| Node::Pat(Pat { hir_id, .. })
2653+
| Node::Arm(Arm { hir_id, .. })
2654+
| Node::Block(Block { hir_id, .. })
2655+
| Node::Local(Local { hir_id, .. })
2656+
| Node::MacroDef(MacroDef { hir_id, .. })
2657+
| Node::Lifetime(Lifetime { hir_id, .. })
2658+
| Node::Param(Param { hir_id, .. })
2659+
| Node::GenericParam(GenericParam { hir_id, .. }) => Some(*hir_id),
2660+
Node::TraitRef(TraitRef { hir_ref_id, .. }) => Some(*hir_ref_id),
2661+
Node::PathSegment(PathSegment { hir_id, .. }) => *hir_id,
2662+
Node::Variant(Variant { id, .. }) => Some(*id),
2663+
Node::Ctor(variant) => variant.ctor_hir_id(),
2664+
Node::Crate(_) | Node::Visibility(_) => None,
2665+
}
2666+
}
26332667
}

src/librustc_middle/mir/interpret/error.rs

+14-5
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ use super::{AllocId, Pointer, RawConst, ScalarMaybeUndef};
33
use crate::mir::interpret::ConstValue;
44
use crate::ty::layout::LayoutError;
55
use crate::ty::query::TyCtxtAt;
6-
use crate::ty::tls;
7-
use crate::ty::{self, layout, Ty};
6+
use crate::ty::{self, layout, tls, FnSig, Ty};
87

98
use rustc_data_structures::sync::Lock;
109
use rustc_errors::{struct_span_err, DiagnosticBuilder, ErrorReported};
@@ -329,7 +328,7 @@ impl fmt::Display for CheckInAllocMsg {
329328
}
330329

331330
/// Error information for when the program caused Undefined Behavior.
332-
pub enum UndefinedBehaviorInfo {
331+
pub enum UndefinedBehaviorInfo<'tcx> {
333332
/// Free-form case. Only for errors that are never caught!
334333
Ub(String),
335334
/// Unreachable code was executed.
@@ -347,6 +346,8 @@ pub enum UndefinedBehaviorInfo {
347346
PointerArithOverflow,
348347
/// Invalid metadata in a wide pointer (using `str` to avoid allocations).
349348
InvalidMeta(&'static str),
349+
/// Invalid drop function in vtable.
350+
InvalidDropFn(FnSig<'tcx>),
350351
/// Reading a C string that does not end within its allocation.
351352
UnterminatedCString(Pointer),
352353
/// Dereferencing a dangling pointer after it got freed.
@@ -380,6 +381,8 @@ pub enum UndefinedBehaviorInfo {
380381
InvalidDiscriminant(ScalarMaybeUndef),
381382
/// Using a pointer-not-to-a-function as function pointer.
382383
InvalidFunctionPointer(Pointer),
384+
/// Using a string that is not valid UTF-8,
385+
InvalidStr(std::str::Utf8Error),
383386
/// Using uninitialized data where it is not allowed.
384387
InvalidUndefBytes(Option<Pointer>),
385388
/// Working with a local that is not currently live.
@@ -391,7 +394,7 @@ pub enum UndefinedBehaviorInfo {
391394
},
392395
}
393396

394-
impl fmt::Display for UndefinedBehaviorInfo {
397+
impl fmt::Display for UndefinedBehaviorInfo<'_> {
395398
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
396399
use UndefinedBehaviorInfo::*;
397400
match self {
@@ -404,6 +407,11 @@ impl fmt::Display for UndefinedBehaviorInfo {
404407
RemainderByZero => write!(f, "calculating the remainder with a divisor of zero"),
405408
PointerArithOverflow => write!(f, "overflowing in-bounds pointer arithmetic"),
406409
InvalidMeta(msg) => write!(f, "invalid metadata in wide pointer: {}", msg),
410+
InvalidDropFn(sig) => write!(
411+
f,
412+
"invalid drop function signature: got {}, expected exactly one argument which must be a pointer type",
413+
sig
414+
),
407415
UnterminatedCString(p) => write!(
408416
f,
409417
"reading a null-terminated string starting at {} with no null found before end of allocation",
@@ -446,6 +454,7 @@ impl fmt::Display for UndefinedBehaviorInfo {
446454
InvalidFunctionPointer(p) => {
447455
write!(f, "using {} as function pointer but it does not point to a function", p)
448456
}
457+
InvalidStr(err) => write!(f, "this string is not valid UTF-8: {}", err),
449458
InvalidUndefBytes(Some(p)) => write!(
450459
f,
451460
"reading uninitialized memory at {}, but this operation requires initialized memory",
@@ -549,7 +558,7 @@ impl dyn MachineStopType {
549558

550559
pub enum InterpError<'tcx> {
551560
/// The program caused undefined behavior.
552-
UndefinedBehavior(UndefinedBehaviorInfo),
561+
UndefinedBehavior(UndefinedBehaviorInfo<'tcx>),
553562
/// The program did something the interpreter does not support (some of these *might* be UB
554563
/// but the interpreter is not sure).
555564
Unsupported(UnsupportedOpInfo),

0 commit comments

Comments
 (0)