diff --git a/src/Make.pkg b/src/Make.pkg
index fc80cf6e6c9a8e6073476c7c436def6316c9063c..ad7d10bebfb0451d95a35c237f20934bbc0b401d 100644
--- a/src/Make.pkg
+++ b/src/Make.pkg
@@ -83,10 +83,10 @@ $(TARGDIR)/$(TARG).a: _obj/$(TARG).a
 	cp _obj/$(TARG).a "$@"
 
 _go_.$O: $(GOFILES) $(PREREQ)
-	$(GC) $(GCIMPORTS) -o $@ $(GOFILES)
+	$(GC) $(GCIMPORTS) -p $(TARG) -o $@ $(GOFILES)
 
 _gotest_.$O: $(GOFILES) $(GOTESTFILES) $(PREREQ)
-	$(GC) $(GCIMPORTS) -o $@ $(GOFILES) $(GOTESTFILES)
+	$(GC) $(GCIMPORTS) -p $(TARG) -o $@ $(GOFILES) $(GOTESTFILES)
 
 _obj/$(TARG).a: _go_.$O $(OFILES)
 	@mkdir -p _obj/$(dir)
diff --git a/src/cmd/gc/doc.go b/src/cmd/gc/doc.go
index 83be8b7c09d094207725018bb983761944d028df..5bb5e0e146bf44e73069e6eeb196e213fc399aec 100644
--- a/src/cmd/gc/doc.go
+++ b/src/cmd/gc/doc.go
@@ -35,6 +35,9 @@ Flags:
 		output file, default file.6 for 6g, etc.
 	-e
 		normally the compiler quits after 10 errors; -e prints all errors
+	-p path
+		assume that path is the eventual import path for this code,
+		and diagnose any attempt to import a package that depends on it.
 	-L
 		show entire file path when printing line numbers in errors
 	-I dir1 -I dir2
diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h
index 4c543fc39556dc4548f9a1643201749b5ef6b124..f72799420b13cae7a863a3976274eca486d201bb 100644
--- a/src/cmd/gc/go.h
+++ b/src/cmd/gc/go.h
@@ -773,6 +773,7 @@ EXTERN	Pkg*	phash[128];
 EXTERN	int	tptr;		// either TPTR32 or TPTR64
 extern	char*	runtimeimport;
 extern	char*	unsafeimport;
+EXTERN	char*	myimportpath;
 EXTERN	Idir*	idirs;
 
 EXTERN	Type*	types[NTYPE];
diff --git a/src/cmd/gc/go.y b/src/cmd/gc/go.y
index 2ec8d888b50a2977438ecbcf9f1d5971a490b1a5..a5e92bd4d436704d318c85b2289c6d97ff11fa31 100644
--- a/src/cmd/gc/go.y
+++ b/src/cmd/gc/go.y
@@ -243,11 +243,11 @@ import_package:
 			importpkg->name = $2->name;
 			pkglookup($2->name, nil)->npkg++;
 		} else if(strcmp(importpkg->name, $2->name) != 0)
-			yyerror("conflicting names %s and %s for package %Z", importpkg->name, $2->name, importpkg->path);
+			yyerror("conflicting names %s and %s for package \"%Z\"", importpkg->name, $2->name, importpkg->path);
 		importpkg->direct = 1;
 		
 		if(safemode && !curio.importsafe)
-			yyerror("cannot import unsafe package %Z", importpkg->path);
+			yyerror("cannot import unsafe package \"%Z\"", importpkg->path);
 	}
 
 import_safety:
@@ -1686,7 +1686,11 @@ hidden_import:
 			p->name = $2->name;
 			pkglookup($2->name, nil)->npkg++;
 		} else if(strcmp(p->name, $2->name) != 0)
-			yyerror("conflicting names %s and %s for package %Z", p->name, $2->name, p->path);
+			yyerror("conflicting names %s and %s for package \"%Z\"", p->name, $2->name, p->path);
+		if(!incannedimport && myimportpath != nil && strcmp($3.u.sval->s, myimportpath) == 0) {
+			yyerror("import \"%Z\": package depends on \"%Z\" (import cycle)", importpkg->path, $3.u.sval);
+			errorexit();
+		}
 	}
 |	LVAR hidden_pkg_importsym hidden_type ';'
 	{
diff --git a/src/cmd/gc/lex.c b/src/cmd/gc/lex.c
index c0aea9095a1a988553e9f1e94a4b374ae1de5000..0290fb1314513fae1e1f350bb02ef4a723ac687e 100644
--- a/src/cmd/gc/lex.c
+++ b/src/cmd/gc/lex.c
@@ -88,6 +88,7 @@ usage(void)
 	print("  -h panic on an error\n");
 	print("  -m print about moves to heap\n");
 	print("  -o file specify output file\n");
+	print("  -p assumed import path for this code\n");
 	print("  -s disable escape analysis\n");
 	print("  -u disable package unsafe\n");
 	print("  -w print the parse tree after typing\n");
@@ -154,6 +155,10 @@ main(int argc, char *argv[])
 	case 'o':
 		outfile = EARGF(usage());
 		break;
+	
+	case 'p':
+		myimportpath = EARGF(usage());
+		break;
 
 	case 'I':
 		addidir(EARGF(usage()));
@@ -479,6 +484,11 @@ importfile(Val *f, int line)
 		errorexit();
 	}
 
+	if(myimportpath != nil && strcmp(f->u.sval->s, myimportpath) == 0) {
+		yyerror("import \"%Z\" while compiling that package (import cycle)", f->u.sval);
+		errorexit();
+	}
+
 	if(strcmp(f->u.sval->s, "unsafe") == 0) {
 		if(safemode) {
 			yyerror("cannot import package unsafe");
@@ -500,14 +510,14 @@ importfile(Val *f, int line)
 	}
 
 	if(!findpkg(path)) {
-		yyerror("can't find import: %Z", f->u.sval);
+		yyerror("can't find import: \"%Z\"", f->u.sval);
 		errorexit();
 	}
 	importpkg = mkpkg(path);
 
 	imp = Bopen(namebuf, OREAD);
 	if(imp == nil) {
-		yyerror("can't open import: %Z: %r", f->u.sval);
+		yyerror("can't open import: \"%Z\": %r", f->u.sval);
 		errorexit();
 	}
 	file = strdup(namebuf);
@@ -564,7 +574,7 @@ importfile(Val *f, int line)
 			continue;
 		return;
 	}
-	yyerror("no import in: %Z", f->u.sval);
+	yyerror("no import in \"%Z\"", f->u.sval);
 	unimportfile();
 }
 
@@ -1938,7 +1948,7 @@ mkpackage(char* pkgname)
 					// errors if a conflicting top-level name is
 					// introduced by a different file.
 					if(!s->def->used && !nsyntaxerrors)
-						yyerrorl(s->def->lineno, "imported and not used: %Z", s->def->pkg->path);
+						yyerrorl(s->def->lineno, "imported and not used: \"%Z\"", s->def->pkg->path);
 					s->def = N;
 					continue;
 				}
@@ -1946,7 +1956,7 @@ mkpackage(char* pkgname)
 					// throw away top-level name left over
 					// from previous import . "x"
 					if(s->def->pack != N && !s->def->pack->used && !nsyntaxerrors) {
-						yyerrorl(s->def->pack->lineno, "imported and not used: %Z", s->def->pack->pkg->path);
+						yyerrorl(s->def->pack->lineno, "imported and not used: \"%Z\"", s->def->pack->pkg->path);
 						s->def->pack->used = 1;
 					}
 					s->def = N;
diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c
index ae163b29a65bb8ea0c1cb27839378e41974bb4b0..9448c3ffe8efbb1836e430bf5f0cbada19c93018 100644
--- a/src/cmd/gc/subr.c
+++ b/src/cmd/gc/subr.c
@@ -405,7 +405,7 @@ importdot(Pkg *opkg, Node *pack)
 	}
 	if(n == 0) {
 		// can't possibly be used - there were no symbols
-		yyerrorl(pack->lineno, "imported and not used: %Z", opkg->path);
+		yyerrorl(pack->lineno, "imported and not used: \"%Z\"", opkg->path);
 	}
 }