Skip to content

Commit a5e7bb3

Browse files
committed
Auto merge of #63043 - Centril:rollup-f4baee4, r=Centril
Rollup of 6 pull requests Successful merges: - #62423 (Fix cycle error with existential types) - #62979 (Cleanup save-analysis JsonDumper) - #62982 (Don't access a static just for its size and alignment) - #63013 (add `repr(transparent)` to `IoSliceMut` where missing) - #63014 (Stop bare trait lint applying to macro call sites) - #63036 (Add lib section to rustc_lexer's Cargo.toml) Failed merges: r? @ghost
2 parents 0e9b465 + 51769b3 commit a5e7bb3

26 files changed

+388
-219
lines changed

src/librustc/hir/lowering.rs

+15-7
Original file line numberDiff line numberDiff line change
@@ -5753,13 +5753,21 @@ impl<'a> LoweringContext<'a> {
57535753
}
57545754

57555755
fn maybe_lint_bare_trait(&self, span: Span, id: NodeId, is_global: bool) {
5756-
self.sess.buffer_lint_with_diagnostic(
5757-
builtin::BARE_TRAIT_OBJECTS,
5758-
id,
5759-
span,
5760-
"trait objects without an explicit `dyn` are deprecated",
5761-
builtin::BuiltinLintDiagnostics::BareTraitObject(span, is_global),
5762-
)
5756+
// FIXME(davidtwco): This is a hack to detect macros which produce spans of the
5757+
// call site which do not have a macro backtrace. See #61963.
5758+
let is_macro_callsite = self.sess.source_map()
5759+
.span_to_snippet(span)
5760+
.map(|snippet| snippet.starts_with("#["))
5761+
.unwrap_or(true);
5762+
if !is_macro_callsite {
5763+
self.sess.buffer_lint_with_diagnostic(
5764+
builtin::BARE_TRAIT_OBJECTS,
5765+
id,
5766+
span,
5767+
"trait objects without an explicit `dyn` are deprecated",
5768+
builtin::BuiltinLintDiagnostics::BareTraitObject(span, is_global),
5769+
)
5770+
}
57635771
}
57645772

57655773
fn wrap_in_try_constructor(

src/librustc_lexer/Cargo.toml

+6
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,9 @@ edition = "2018"
77
# Note that this crate purposefully does not depend on other rustc crates
88
[dependencies]
99
unicode-xid = { version = "0.1.0", optional = true }
10+
11+
# Note: do not remove this blank `[lib]` section.
12+
# This will be used when publishing this crate as `rustc-ap-rustc_lexer`.
13+
[lib]
14+
doctest = false
15+
name = "rustc_lexer"

src/librustc_mir/borrow_check/nll/type_check/mod.rs

+33-5
Original file line numberDiff line numberDiff line change
@@ -1281,15 +1281,43 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
12811281
let opaque_defn_ty = tcx.type_of(opaque_def_id);
12821282
let opaque_defn_ty = opaque_defn_ty.subst(tcx, opaque_decl.substs);
12831283
let opaque_defn_ty = renumber::renumber_regions(infcx, &opaque_defn_ty);
1284+
let concrete_is_opaque = infcx
1285+
.resolve_vars_if_possible(&opaque_decl.concrete_ty).is_impl_trait();
1286+
12841287
debug!(
1285-
"eq_opaque_type_and_type: concrete_ty={:?}={:?} opaque_defn_ty={:?}",
1288+
"eq_opaque_type_and_type: concrete_ty={:?}={:?} opaque_defn_ty={:?} \
1289+
concrete_is_opaque={}",
12861290
opaque_decl.concrete_ty,
12871291
infcx.resolve_vars_if_possible(&opaque_decl.concrete_ty),
1288-
opaque_defn_ty
1292+
opaque_defn_ty,
1293+
concrete_is_opaque
12891294
);
1290-
obligations.add(infcx
1291-
.at(&ObligationCause::dummy(), param_env)
1292-
.eq(opaque_decl.concrete_ty, opaque_defn_ty)?);
1295+
1296+
// concrete_is_opaque is `true` when we're using an existential
1297+
// type without 'revealing' it. For example, code like this:
1298+
//
1299+
// existential type Foo: Debug;
1300+
// fn foo1() -> Foo { ... }
1301+
// fn foo2() -> Foo { foo1() }
1302+
//
1303+
// In `foo2`, we're not revealing the type of `Foo` - we're
1304+
// just treating it as the opaque type.
1305+
//
1306+
// When this occurs, we do *not* want to try to equate
1307+
// the concrete type with the underlying defining type
1308+
// of the existential type - this will always fail, since
1309+
// the defining type of an existential type is always
1310+
// some other type (e.g. not itself)
1311+
// Essentially, none of the normal obligations apply here -
1312+
// we're just passing around some unknown opaque type,
1313+
// without actually looking at the underlying type it
1314+
// gets 'revealed' into
1315+
1316+
if !concrete_is_opaque {
1317+
obligations.add(infcx
1318+
.at(&ObligationCause::dummy(), param_env)
1319+
.eq(opaque_decl.concrete_ty, opaque_defn_ty)?);
1320+
}
12931321
}
12941322

12951323
debug!("eq_opaque_type_and_type: equated");

src/librustc_mir/interpret/memory.rs

+41-34
Original file line numberDiff line numberDiff line change
@@ -535,41 +535,48 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
535535
id: AllocId,
536536
liveness: AllocCheck,
537537
) -> InterpResult<'static, (Size, Align)> {
538-
// Regular allocations.
539-
if let Ok(alloc) = self.get(id) {
540-
return Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align));
541-
}
542-
// Function pointers.
543-
if let Ok(_) = self.get_fn_alloc(id) {
544-
return if let AllocCheck::Dereferencable = liveness {
545-
// The caller requested no function pointers.
546-
err!(DerefFunctionPointer)
547-
} else {
548-
Ok((Size::ZERO, Align::from_bytes(1).unwrap()))
549-
};
550-
}
551-
// Foreign statics.
552-
// Can't do this in the match argument, we may get cycle errors since the lock would
553-
// be held throughout the match.
554-
let alloc = self.tcx.alloc_map.lock().get(id);
555-
match alloc {
556-
Some(GlobalAlloc::Static(did)) => {
557-
assert!(self.tcx.is_foreign_item(did));
558-
// Use size and align of the type
559-
let ty = self.tcx.type_of(did);
560-
let layout = self.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap();
561-
return Ok((layout.size, layout.align.abi));
538+
// Don't use `self.get` here as that will
539+
// a) cause cycles in case `id` refers to a static
540+
// b) duplicate a static's allocation in miri
541+
match self.alloc_map.get_or(id, || Err(())) {
542+
Ok((_, alloc)) => Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align)),
543+
Err(()) => {
544+
// Not a local allocation, check the global `tcx.alloc_map`.
545+
546+
// Can't do this in the match argument, we may get cycle errors since the lock would
547+
// be held throughout the match.
548+
let alloc = self.tcx.alloc_map.lock().get(id);
549+
match alloc {
550+
Some(GlobalAlloc::Static(did)) => {
551+
// Use size and align of the type.
552+
let ty = self.tcx.type_of(did);
553+
let layout = self.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap();
554+
Ok((layout.size, layout.align.abi))
555+
},
556+
Some(GlobalAlloc::Memory(alloc)) =>
557+
// Need to duplicate the logic here, because the global allocations have
558+
// different associated types than the interpreter-local ones.
559+
Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align)),
560+
Some(GlobalAlloc::Function(_)) => {
561+
if let AllocCheck::Dereferencable = liveness {
562+
// The caller requested no function pointers.
563+
err!(DerefFunctionPointer)
564+
} else {
565+
Ok((Size::ZERO, Align::from_bytes(1).unwrap()))
566+
}
567+
},
568+
// The rest must be dead.
569+
None => if let AllocCheck::MaybeDead = liveness {
570+
// Deallocated pointers are allowed, we should be able to find
571+
// them in the map.
572+
Ok(*self.dead_alloc_map.get(&id)
573+
.expect("deallocated pointers should all be recorded in \
574+
`dead_alloc_map`"))
575+
} else {
576+
err!(DanglingPointerDeref)
577+
},
578+
}
562579
}
563-
_ => {}
564-
}
565-
// The rest must be dead.
566-
if let AllocCheck::MaybeDead = liveness {
567-
// Deallocated pointers are allowed, we should be able to find
568-
// them in the map.
569-
Ok(*self.dead_alloc_map.get(&id)
570-
.expect("deallocated pointers should all be recorded in `dead_alloc_map`"))
571-
} else {
572-
err!(DanglingPointerDeref)
573580
}
574581
}
575582

src/librustc_save_analysis/dump_visitor.rs

+10-10
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//!
1111
//! SpanUtils is used to manipulate spans. In particular, to extract sub-spans
1212
//! from spans (e.g., the span for `bar` from the above example path).
13-
//! DumpVisitor walks the AST and processes it, and JsonDumper is used for
13+
//! DumpVisitor walks the AST and processes it, and Dumper is used for
1414
//! recording the output.
1515
1616
use rustc::hir::def::{Res, DefKind as HirDefKind};
@@ -38,7 +38,7 @@ use syntax_pos::*;
3838

3939
use crate::{escape, generated_code, id_from_def_id, id_from_node_id, lower_attributes,
4040
PathCollector, SaveContext};
41-
use crate::json_dumper::{Access, DumpOutput, JsonDumper};
41+
use crate::dumper::{Access, Dumper};
4242
use crate::span_utils::SpanUtils;
4343
use crate::sig;
4444

@@ -75,10 +75,10 @@ macro_rules! access_from_vis {
7575
};
7676
}
7777

78-
pub struct DumpVisitor<'l, 'tcx, 'll, O: DumpOutput> {
78+
pub struct DumpVisitor<'l, 'tcx, 'll> {
7979
save_ctxt: SaveContext<'l, 'tcx>,
8080
tcx: TyCtxt<'tcx>,
81-
dumper: &'ll mut JsonDumper<O>,
81+
dumper: &'ll mut Dumper,
8282

8383
span: SpanUtils<'l>,
8484

@@ -92,11 +92,11 @@ pub struct DumpVisitor<'l, 'tcx, 'll, O: DumpOutput> {
9292
// macro_calls: FxHashSet<Span>,
9393
}
9494

95-
impl<'l, 'tcx, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
95+
impl<'l, 'tcx, 'll> DumpVisitor<'l, 'tcx, 'll> {
9696
pub fn new(
9797
save_ctxt: SaveContext<'l, 'tcx>,
98-
dumper: &'ll mut JsonDumper<O>,
99-
) -> DumpVisitor<'l, 'tcx, 'll, O> {
98+
dumper: &'ll mut Dumper,
99+
) -> DumpVisitor<'l, 'tcx, 'll> {
100100
let span_utils = SpanUtils::new(&save_ctxt.tcx.sess);
101101
DumpVisitor {
102102
tcx: save_ctxt.tcx,
@@ -111,7 +111,7 @@ impl<'l, 'tcx, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
111111

112112
fn nest_scope<F>(&mut self, scope_id: NodeId, f: F)
113113
where
114-
F: FnOnce(&mut DumpVisitor<'l, 'tcx, 'll, O>),
114+
F: FnOnce(&mut DumpVisitor<'l, 'tcx, 'll>),
115115
{
116116
let parent_scope = self.cur_scope;
117117
self.cur_scope = scope_id;
@@ -121,7 +121,7 @@ impl<'l, 'tcx, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
121121

122122
fn nest_tables<F>(&mut self, item_id: NodeId, f: F)
123123
where
124-
F: FnOnce(&mut DumpVisitor<'l, 'tcx, 'll, O>),
124+
F: FnOnce(&mut DumpVisitor<'l, 'tcx, 'll>),
125125
{
126126
let item_def_id = self.tcx.hir().local_def_id_from_node_id(item_id);
127127
if self.tcx.has_typeck_tables(item_def_id) {
@@ -1311,7 +1311,7 @@ impl<'l, 'tcx, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
13111311
}
13121312
}
13131313

1314-
impl<'l, 'tcx, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tcx, 'll, O> {
1314+
impl<'l, 'tcx, 'll> Visitor<'l> for DumpVisitor<'l, 'tcx, 'll> {
13151315
fn visit_mod(&mut self, m: &'l ast::Mod, span: Span, attrs: &[ast::Attribute], id: NodeId) {
13161316
// Since we handle explicit modules ourselves in visit_item, this should
13171317
// only get called for the root module of a crate.

src/librustc_save_analysis/json_dumper.rs src/librustc_save_analysis/dumper.rs

+7-54
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,33 @@
1-
use std::io::Write;
2-
31
use rls_data::config::Config;
42
use rls_data::{self, Analysis, CompilationOptions, CratePreludeData, Def, DefKind, Impl, Import,
53
MacroRef, Ref, RefKind, Relation};
64
use rls_span::{Column, Row};
75

8-
use log::error;
9-
106
#[derive(Debug)]
117
pub struct Access {
128
pub reachable: bool,
139
pub public: bool,
1410
}
1511

16-
pub struct JsonDumper<O: DumpOutput> {
12+
pub struct Dumper {
1713
result: Analysis,
1814
config: Config,
19-
output: O,
20-
}
21-
22-
pub trait DumpOutput {
23-
fn dump(&mut self, result: &Analysis);
24-
}
25-
26-
pub struct WriteOutput<'b, W: Write> {
27-
output: &'b mut W,
28-
}
29-
30-
impl<'b, W: Write> DumpOutput for WriteOutput<'b, W> {
31-
fn dump(&mut self, result: &Analysis) {
32-
if let Err(e) = serde_json::to_writer(self.output.by_ref(), result) {
33-
error!("Can't serialize save-analysis: {:?}", e);
34-
}
35-
}
36-
}
37-
38-
pub struct CallbackOutput<'b> {
39-
callback: &'b mut dyn FnMut(&Analysis),
40-
}
41-
42-
impl<'b> DumpOutput for CallbackOutput<'b> {
43-
fn dump(&mut self, result: &Analysis) {
44-
(self.callback)(result)
45-
}
4615
}
4716

48-
impl<'b, W: Write> JsonDumper<WriteOutput<'b, W>> {
49-
pub fn new(writer: &'b mut W, config: Config) -> JsonDumper<WriteOutput<'b, W>> {
50-
JsonDumper {
51-
output: WriteOutput { output: writer },
17+
impl Dumper {
18+
pub fn new(config: Config) -> Dumper {
19+
Dumper {
5220
config: config.clone(),
5321
result: Analysis::new(config),
5422
}
5523
}
56-
}
57-
58-
impl<'b> JsonDumper<CallbackOutput<'b>> {
59-
pub fn with_callback(
60-
callback: &'b mut dyn FnMut(&Analysis),
61-
config: Config,
62-
) -> JsonDumper<CallbackOutput<'b>> {
63-
JsonDumper {
64-
output: CallbackOutput { callback },
65-
config: config.clone(),
66-
result: Analysis::new(config),
67-
}
68-
}
69-
}
7024

71-
impl<O: DumpOutput> Drop for JsonDumper<O> {
72-
fn drop(&mut self) {
73-
self.output.dump(&self.result);
25+
pub fn to_output(self, f: impl FnOnce(&Analysis)) {
26+
f(&self.result)
7427
}
7528
}
7629

77-
impl<'b, O: DumpOutput + 'b> JsonDumper<O> {
30+
impl Dumper {
7831
pub fn crate_prelude(&mut self, data: CratePreludeData) {
7932
self.result.prelude = Some(data)
8033
}

0 commit comments

Comments
 (0)